From: lsedlak Date: Mon, 1 Jul 2013 15:47:09 +0000 (+0200) Subject: Added support to generate interfaces from Choices and Cases. X-Git-Tag: releasepom-0.1.0~317^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=c9006d027a5c5b639e57aa7b8484ec1ff3497dc8 Added support to generate interfaces from Choices and Cases. Added implementation to support generation of generated types from Choice and Case schema nodes from yang models into BindingGeneratorImpl; Added test case and test files for test of generation of Generated Types; Fixed bug in GeneratorUtil when imports were generated wrongly if the name of type was same as the name of interface/class. Signed-off-by: Lukas Sedlak --- 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 2235bfb2a3..8b680509dd 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 @@ -7,13 +7,22 @@ */ package org.opendaylight.controller.sal.binding.generator.impl; +import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*; +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 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; import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator; import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider; -import org.opendaylight.controller.sal.binding.model.api.*; +import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.controller.sal.binding.model.api.GeneratedType; +import org.opendaylight.controller.sal.binding.model.api.Type; import org.opendaylight.controller.sal.binding.model.api.type.builder.*; import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl; import org.opendaylight.controller.yang.binding.Notification; @@ -26,13 +35,6 @@ import org.opendaylight.controller.yang.model.util.DataNodeIterator; import org.opendaylight.controller.yang.model.util.ExtendedType; import org.opendaylight.controller.yang.model.util.SchemaContextUtil; -import java.util.*; -import java.util.concurrent.Future; - -import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*; -import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode; -import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule; - public final class BindingGeneratorImpl implements BindingGenerator { private Map> genTypeBuilders; @@ -46,12 +48,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { @Override public List generateTypes(final SchemaContext context) { if (context == null) { - throw new IllegalArgumentException("Schema Context reference " - + "cannot be NULL!"); + throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } if (context.getModules() == null) { - throw new IllegalStateException("Schema Context does not contain " - + "defined modules!"); + throw new IllegalStateException("Schema Context does not contain defined modules!"); } final List generatedTypes = new ArrayList<>(); @@ -64,6 +64,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); generatedTypes.addAll(allContainersToGenTypes(module)); generatedTypes.addAll(allListsToGenTypes(module)); + generatedTypes.addAll(allChoicesToGenTypes(module)); generatedTypes.addAll(allAugmentsToGenTypes(module)); generatedTypes.addAll(allRPCMethodsToGenType(module)); generatedTypes.addAll(allNotificationsToGenType(module)); @@ -74,19 +75,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { } @Override - public List generateTypes(final SchemaContext context, - final Set modules) { + public List generateTypes(final SchemaContext context, final Set modules) { if (context == null) { - throw new IllegalArgumentException("Schema Context reference " - + "cannot be NULL!"); + throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } if (context.getModules() == null) { - throw new IllegalStateException("Schema Context does not contain " - + "defined modules!"); + throw new IllegalStateException("Schema Context does not contain defined modules!"); } if (modules == null) { - throw new IllegalArgumentException("Sef of Modules cannot be " - + "NULL!"); + throw new IllegalArgumentException("Sef of Modules cannot be NULL!"); } final List filteredGenTypes = new ArrayList<>(); @@ -101,11 +98,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); generatedTypes.addAll(allContainersToGenTypes(contextModule)); generatedTypes.addAll(allListsToGenTypes(contextModule)); + generatedTypes.addAll(allChoicesToGenTypes(contextModule)); generatedTypes.addAll(allAugmentsToGenTypes(contextModule)); generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); generatedTypes.addAll(allNotificationsToGenType(contextModule)); - generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, - context)); + generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context)); generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); if (modules.contains(contextModule)) { @@ -117,24 +114,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { private List allTypeDefinitionsToGenTypes(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } if (module.getName() == null) { throw new IllegalArgumentException("Module name cannot be NULL!"); } if (module.getTypeDefinitions() == null) { - throw new IllegalArgumentException("Type Definitions for module " - + module.getName() + " cannot be NULL!"); + throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!"); } - final Set> typeDefinitions = module - .getTypeDefinitions(); + final Set> typeDefinitions = module.getTypeDefinitions(); final List generatedTypes = new ArrayList<>(); for (final TypeDefinition typedef : typeDefinitions) { if (typedef != null) { - final Type type = ((TypeProviderImpl) typeProvider) - .generatedTypeForExtendedDefinitionType(typedef); + final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef); if ((type != null) && !generatedTypes.contains(type)) { generatedTypes.add(type); } @@ -145,8 +138,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { private List allContainersToGenTypes(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } if (module.getName() == null) { @@ -154,9 +146,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { } if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child " - + "Nodes in module " + module.getName() + " cannot be " - + "NULL!"); + throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() + + " cannot be NULL!"); } final List generatedTypes = new ArrayList<>(); @@ -171,8 +162,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { private List allListsToGenTypes(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } if (module.getName() == null) { @@ -180,9 +170,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { } if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child " - + "Nodes in module " + module.getName() + " cannot be " - + "NULL!"); + throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() + + " cannot be NULL!"); } final List generatedTypes = new ArrayList<>(); @@ -197,88 +186,94 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } - private List allAugmentsToGenTypes(final Module module) { + private List allChoicesToGenTypes(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } - if (module.getName() == null) { throw new IllegalArgumentException("Module name cannot be NULL!"); } + final DataNodeIterator it = new DataNodeIterator(module); + final List choiceNodes = it.allChoices(); + final String basePackageName = moduleNamespaceToPackageName(module); + + final List generatedTypes = new ArrayList<>(); + for (final ChoiceNode choice : choiceNodes) { + if (choice != null) { + generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice)); + } + } + return generatedTypes; + } + + private List allAugmentsToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module reference cannot be NULL!"); + } + if (module.getName() == null) { + throw new IllegalArgumentException("Module name cannot be NULL!"); + } if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of " - + "Augmentation Definitions in module " + module.getName() - + " cannot be NULL!"); + throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module " + + module.getName() + " cannot be NULL!"); } final List generatedTypes = new ArrayList<>(); final String basePackageName = moduleNamespaceToPackageName(module); final List augmentations = resolveAugmentations(module); for (final AugmentationSchema augment : augmentations) { - generatedTypes.addAll(augmentationToGenTypes(basePackageName, - augment)); + generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment)); } return generatedTypes; } private List resolveAugmentations(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } if (module.getAugmentations() == null) { throw new IllegalStateException("Augmentations Set cannot be NULL!"); } final Set augmentations = module.getAugmentations(); - final List sortedAugmentations = new ArrayList<>( - augmentations); - Collections.sort(sortedAugmentations, - new Comparator() { - - @Override - public int compare(AugmentationSchema augSchema1, - AugmentationSchema augSchema2) { - - if (augSchema1.getTargetPath().getPath().size() > augSchema2 - .getTargetPath().getPath().size()) { - return 1; - } else if (augSchema1.getTargetPath().getPath().size() < augSchema2 - .getTargetPath().getPath().size()) { - return -1; - } - return 0; + final List sortedAugmentations = new ArrayList<>(augmentations); + Collections.sort(sortedAugmentations, new Comparator() { - } - }); + @Override + public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) { + + if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) { + return 1; + } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) { + return -1; + } + return 0; + + } + }); return sortedAugmentations; } private GeneratedType moduleToDataType(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } - final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder( - module, "Data"); + final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); final String basePackageName = moduleNamespaceToPackageName(module); if (moduleDataTypeBuilder != null) { final Set dataNodes = module.getChildNodes(); - resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, - dataNodes); + resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes); } return moduleDataTypeBuilder.toInstance(); } private List allRPCMethodsToGenType(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } if (module.getName() == null) { @@ -286,24 +281,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { } if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of " - + "RPC Method Definitions in module " + module.getName() - + " cannot be NULL!"); + throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module " + + module.getName() + " cannot be NULL!"); } final String basePackageName = moduleNamespaceToPackageName(module); final Set rpcDefinitions = module.getRpcs(); final List genRPCTypes = new ArrayList<>(); - final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, - "Service"); + final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service"); final Type future = Types.typeForClass(Future.class); for (final RpcDefinition rpc : rpcDefinitions) { if (rpc != null) { - String rpcName = parseToClassName(rpc.getQName() - .getLocalName()); - MethodSignatureBuilder method = interfaceBuilder - .addMethod(rpcName); + String rpcName = parseToClassName(rpc.getQName().getLocalName()); + MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcName); final List rpcInOut = new ArrayList<>(); @@ -312,8 +303,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (input != null) { rpcInOut.add(new DataNodeIterator(input)); - GeneratedTypeBuilder inType = addRawInterfaceDefinition( - basePackageName, input, rpcName); + GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes()); Type inTypeInstance = inType.toInstance(); genRPCTypes.add(inTypeInstance); @@ -324,30 +314,26 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (output != null) { rpcInOut.add(new DataNodeIterator(output)); - GeneratedTypeBuilder outType = addRawInterfaceDefinition( - basePackageName, output, rpcName); + GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes()); outTypeInstance = outType.toInstance(); genRPCTypes.add(outTypeInstance); } - final Type rpcRes = Types.parameterizedTypeFor( - Types.typeForClass(RpcResult.class), outTypeInstance); + final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance); method.setReturnType(Types.parameterizedTypeFor(future, rpcRes)); for (DataNodeIterator it : rpcInOut) { List nContainers = it.allContainers(); if ((nContainers != null) && !nContainers.isEmpty()) { for (final ContainerSchemaNode container : nContainers) { - genRPCTypes.add(containerToGenType(basePackageName, - container)); + genRPCTypes.add(containerToGenType(basePackageName, container)); } } List nLists = it.allLists(); if ((nLists != null) && !nLists.isEmpty()) { for (final ListSchemaNode list : nLists) { - genRPCTypes.addAll(listToGenType(basePackageName, - list)); + genRPCTypes.addAll(listToGenType(basePackageName, list)); } } } @@ -359,8 +345,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { private List allNotificationsToGenType(final Module module) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } if (module.getName() == null) { @@ -368,15 +353,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { } if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of " - + "Notification Definitions in module " + module.getName() - + " cannot be NULL!"); + throw new IllegalArgumentException("Reference to Set of Notification Definitions in module " + + module.getName() + " cannot be NULL!"); } final String basePackageName = moduleNamespaceToPackageName(module); final List genNotifyTypes = new ArrayList<>(); - final Set notifications = module - .getNotifications(); + final Set notifications = module.getNotifications(); for (final NotificationDefinition notification : notifications) { if (notification != null) { @@ -384,29 +367,25 @@ public final class BindingGeneratorImpl implements BindingGenerator { // Containers for (ContainerSchemaNode node : it.allContainers()) { - genNotifyTypes - .add(containerToGenType(basePackageName, node)); + genNotifyTypes.add(containerToGenType(basePackageName, node)); } // Lists for (ListSchemaNode node : it.allLists()) { genNotifyTypes.addAll(listToGenType(basePackageName, node)); } - final GeneratedTypeBuilder notificationTypeBuilder = addRawInterfaceDefinition( - basePackageName, notification); - notificationTypeBuilder.addImplementsType(Types - .typeForClass(Notification.class)); + final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName, + notification); + notificationTypeBuilder.addImplementsType(Types.typeForClass(Notification.class)); // Notification object - resolveDataSchemaNodes(basePackageName, - notificationTypeBuilder, notification.getChildNodes()); + resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes()); genNotifyTypes.add(notificationTypeBuilder.toInstance()); } } return genNotifyTypes; } - private List allIdentitiesToGenTypes(final Module module, - final SchemaContext context) { - List genTypes = new ArrayList(); + private List allIdentitiesToGenTypes(final Module module, final SchemaContext context) { + List genTypes = new ArrayList<>(); final Set schemaIdentities = module.getIdentities(); @@ -414,38 +393,30 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (schemaIdentities != null && !schemaIdentities.isEmpty()) { for (final IdentitySchemaNode identity : schemaIdentities) { - genTypes.add(identityToGenType(basePackageName, identity, - context)); + genTypes.add(identityToGenType(basePackageName, identity, context)); } } return genTypes; } - private GeneratedType identityToGenType(final String basePackageName, - IdentitySchemaNode identity, SchemaContext context) { + private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity, + final SchemaContext context) { if (identity == null) { return null; } - final String packageName = packageNameForGeneratedType(basePackageName, - identity.getPath()); - - final String genTypeName = parseToClassName(identity.getQName() - .getLocalName()); - final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl( - packageName, genTypeName); + final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); + final String genTypeName = parseToClassName(identity.getQName().getLocalName()); + final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName); IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); if (baseIdentity != null) { - Module baseIdentityParentModule = SchemaContextUtil.findParentModule( - context, baseIdentity); + Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - final String returnTypeName = parseToClassName(baseIdentity - .getQName().getLocalName()); + final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName()); - GeneratedTransferObject gto = new GeneratedTOBuilderImpl( - returnTypePkgName, returnTypeName).toInstance(); + GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); newType.setExtendsType(gto); } else { newType.setExtendsType(Types.getBaseIdentityTO()); @@ -454,10 +425,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { return newType.toInstance(); } - private List allGroupingsToGenTypes(Module module) { + private List allGroupingsToGenTypes(final Module module) { final List genTypes = new ArrayList<>(); final String basePackageName = moduleNamespaceToPackageName(module); - Set groupings = module.getGroupings(); + final Set groupings = module.getGroupings(); if (groupings != null && !groupings.isEmpty()) { for (final GroupingDefinition grouping : groupings) { genTypes.add(groupingToGenType(basePackageName, grouping)); @@ -466,24 +437,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genTypes; } - private GeneratedType groupingToGenType(final String basePackageName, - GroupingDefinition grouping) { + private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) { if (grouping == null) { return null; } - final String packageName = packageNameForGeneratedType(basePackageName, - grouping.getPath()); + final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath()); final Set schemaNodes = grouping.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition( - packageName, grouping); + final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); return typeBuilder.toInstance(); } - private EnumTypeDefinition enumTypeDefFromExtendedType( - final TypeDefinition typeDefinition) { + private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition typeDefinition) { if (typeDefinition != null) { if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) { return (EnumTypeDefinition) typeDefinition.getBaseType(); @@ -494,16 +461,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { return null; } - private EnumBuilder resolveInnerEnumFromTypeDefinition( - final EnumTypeDefinition enumTypeDef, final String enumName, + private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilder typeBuilder) { - if ((enumTypeDef != null) && (typeBuilder != null) - && (enumTypeDef.getQName() != null) + if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null) && (enumTypeDef.getQName().getLocalName() != null)) { final String enumerationName = parseToClassName(enumName); - final EnumBuilder enumBuilder = typeBuilder - .addEnumeration(enumerationName); + final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); if (enumBuilder != null) { final List enums = enumTypeDef.getValues(); @@ -511,8 +475,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { int listIndex = 0; for (final EnumPair enumPair : enums) { if (enumPair != null) { - final String enumPairName = parseToClassName(enumPair - .getName()); + final String enumPairName = parseToClassName(enumPair.getName()); Integer enumPairValue = enumPair.getValue(); if (enumPairValue == null) { @@ -529,11 +492,9 @@ public final class BindingGeneratorImpl implements BindingGenerator { return null; } - private GeneratedTypeBuilder moduleTypeBuilder(final Module module, - final String postfix) { + private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { if (module == null) { - throw new IllegalArgumentException( - "Module reference cannot be NULL!"); + throw new IllegalArgumentException("Module reference cannot be NULL!"); } String packageName = moduleNamespaceToPackageName(module); final String moduleName = parseToClassName(module.getName()) + postfix; @@ -542,18 +503,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { } - private List augmentationToGenTypes(final String augmentPackageName, - final AugmentationSchema augSchema) { + private List augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) { if (augmentPackageName == null) { throw new IllegalArgumentException("Package Name cannot be NULL!"); } if (augSchema == null) { - throw new IllegalArgumentException( - "Augmentation Schema cannot be NULL!"); + throw new IllegalArgumentException("Augmentation Schema cannot be NULL!"); } if (augSchema.getTargetPath() == null) { - throw new IllegalStateException( - "Augmentation Schema does not contain Target Path (Target Path is NULL)."); + throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL)."); } final List genTypes = new ArrayList<>(); @@ -561,80 +519,62 @@ public final class BindingGeneratorImpl implements BindingGenerator { // EVERY augmented interface will extends Augmentation interface // and DataObject interface!!! final SchemaPath targetPath = augSchema.getTargetPath(); - final DataSchemaNode targetSchemaNode = findDataSchemaNode( - schemaContext, targetPath); + final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null) && (targetSchemaNode.getQName().getLocalName() != null)) { - final Module targetModule = findParentModule(schemaContext, - targetSchemaNode); + final Module targetModule = findParentModule(schemaContext, targetSchemaNode); final String targetBasePackage = moduleNamespaceToPackageName(targetModule); - final String targetPackageName = packageNameForGeneratedType( - targetBasePackage, targetSchemaNode.getPath()); + final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); - final String targetSchemaNodeName = targetSchemaNode.getQName() - .getLocalName(); + final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); final Set augChildNodes = augSchema.getChildNodes(); - final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition( - augmentPackageName, targetPackageName, - targetSchemaNodeName, augSchema); + final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, + targetPackageName, targetSchemaNodeName, augSchema); if (augTypeBuilder != null) { genTypes.add(augTypeBuilder.toInstance()); } - genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, - augChildNodes)); + genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); } return genTypes; } - private GeneratedTypeBuilder addRawAugmentGenTypeDefinition( - final String augmentPackageName, final String targetPackageName, - final String targetSchemaNodeName, - final AugmentationSchema augSchema) { + private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName, + final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) { final String targetTypeName = parseToClassName(targetSchemaNodeName); - Map augmentBuilders = genTypeBuilders - .get(augmentPackageName); + Map augmentBuilders = genTypeBuilders.get(augmentPackageName); if (augmentBuilders == null) { augmentBuilders = new HashMap<>(); genTypeBuilders.put(augmentPackageName, augmentBuilders); } - final String augTypeName = augGenTypeName(augmentBuilders, - targetTypeName); - final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, - targetTypeName); + final String augTypeName = augGenTypeName(augmentBuilders, targetTypeName); + final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName); final Set augChildNodes = augSchema.getChildNodes(); - final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl( - augmentPackageName, augTypeName); + final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); augTypeBuilder.addImplementsType(Types.DATA_OBJECT); - augTypeBuilder.addImplementsType(Types - .augmentationTypeFor(targetTypeRef)); + augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); - augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, - augChildNodes); + augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); augmentBuilders.put(augTypeName, augTypeBuilder); return augTypeBuilder; } - private List augmentationBodyToGenTypes( - final String augBasePackageName, + private List augmentationBodyToGenTypes(final String augBasePackageName, final Set augChildNodes) { final List genTypes = new ArrayList<>(); final List augSchemaIts = new ArrayList<>(); for (final DataSchemaNode childNode : augChildNodes) { if (childNode instanceof DataNodeContainer) { - augSchemaIts.add(new DataNodeIterator( - (DataNodeContainer) childNode)); + augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode)); if (childNode instanceof ContainerSchemaNode) { - genTypes.add(containerToGenType(augBasePackageName, - (ContainerSchemaNode) childNode)); + genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode)); } else if (childNode instanceof ListSchemaNode) { - genTypes.addAll(listToGenType(augBasePackageName, - (ListSchemaNode) childNode)); + genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode)); } } } @@ -645,8 +585,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { if ((augContainers != null) && !augContainers.isEmpty()) { for (final ContainerSchemaNode container : augContainers) { - genTypes.add(containerToGenType(augBasePackageName, - container)); + genTypes.add(containerToGenType(augBasePackageName, container)); } } if ((augLists != null) && !augLists.isEmpty()) { @@ -658,9 +597,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genTypes; } - private String augGenTypeName( - final Map builders, - final String genTypeName) { + private String augGenTypeName(final Map builders, final String genTypeName) { String augTypeName = genTypeName; int index = 1; @@ -671,77 +608,134 @@ public final class BindingGeneratorImpl implements BindingGenerator { return augTypeName; } - private GeneratedType containerToGenType(final String basePackageName, - ContainerSchemaNode containerNode) { + private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) { if (containerNode == null) { return null; } - final String packageName = packageNameForGeneratedType(basePackageName, - containerNode.getPath()); + final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); final Set schemaNodes = containerNode.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition( - packageName, containerNode); + final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); return typeBuilder.toInstance(); } - private GeneratedTypeBuilder resolveDataSchemaNodes( - final String basePackageName, - final GeneratedTypeBuilder typeBuilder, - final Set schemaNodes) { - + private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName, + final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { if ((schemaNodes != null) && (typeBuilder != null)) { for (final DataSchemaNode schemaNode : schemaNodes) { if (schemaNode.isAugmenting()) { continue; } - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, - typeBuilder); + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); } } return typeBuilder; } - private GeneratedTypeBuilder augSchemaNodeToMethods( - final String basePackageName, - final GeneratedTypeBuilder typeBuilder, - final Set schemaNodes) { - + private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName, + final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { if ((schemaNodes != null) && (typeBuilder != null)) { for (final DataSchemaNode schemaNode : schemaNodes) { if (schemaNode.isAugmenting()) { - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, - typeBuilder); + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); } } } return typeBuilder; } - private void addSchemaNodeToBuilderAsMethod(final String basePackageName, - final DataSchemaNode schemaNode, + private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder) { if (schemaNode != null && typeBuilder != null) { if (schemaNode instanceof LeafSchemaNode) { - resolveLeafSchemaNodeAsMethod(typeBuilder, - (LeafSchemaNode) schemaNode); + resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode); } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, - (LeafListSchemaNode) schemaNode); + resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, - (ContainerSchemaNode) schemaNode); + resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, - (ListSchemaNode) schemaNode); + resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); + } else if (schemaNode instanceof ChoiceNode) { + resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode); } } } - private boolean resolveLeafSchemaNodeAsMethod( - final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { + private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, + final ChoiceNode choiceNode) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (typeBuilder == null) { + throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); + } + if (choiceNode == null) { + throw new IllegalArgumentException("Choice Schema Node cannot be NULL!"); + } + + final String choiceName = choiceNode.getQName().getLocalName(); + if (choiceName != null) { + final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); + final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); + constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType); + } + } + + private List choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (choiceNode == null) { + throw new IllegalArgumentException("Choice Schema Node cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); + final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); + choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT); + final GeneratedType choiceType = choiceTypeBuilder.toInstance(); + + generatedTypes.add(choiceType); + final Set caseNodes = choiceNode.getCases(); + if ((caseNodes != null) && !caseNodes.isEmpty()) { + generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes)); + } + return generatedTypes; + } + + private List generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType, + final Set caseNodes) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (refChoiceType == null) { + throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!"); + } + if (caseNodes == null) { + throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!"); + } + + final List generatedTypes = new ArrayList<>(); + for (final ChoiceCaseNode caseNode : caseNodes) { + if (caseNode != null) { + final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); + final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + caseTypeBuilder.addImplementsType(refChoiceType); + + final Set childNodes = caseNode.getChildNodes(); + if (childNodes != null) { + resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); + } + generatedTypes.add(caseTypeBuilder.toInstance()); + } + } + + return generatedTypes; + } + + private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { if ((leaf != null) && (typeBuilder != null)) { final String leafName = leaf.getQName().getLocalName(); String leafDesc = leaf.getDescription(); @@ -754,26 +748,21 @@ public final class BindingGeneratorImpl implements BindingGenerator { Type returnType = null; if (!(typeDef instanceof EnumTypeDefinition)) { - returnType = typeProvider - .javaTypeForSchemaDefinitionType(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); } else { final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef); - final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition( - enumTypeDef, leafName, typeBuilder); + final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, + typeBuilder); if (enumBuilder != null) { - returnType = new ReferencedTypeImpl( - enumBuilder.getPackageName(), - enumBuilder.getName()); + returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); } - ((TypeProviderImpl) typeProvider).putReferencedType( - leaf.getPath(), returnType); + ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); } if (returnType != null) { constructGetter(typeBuilder, leafName, leafDesc, returnType); if (!leaf.isConfiguration()) { - constructSetter(typeBuilder, leafName, leafDesc, - returnType); + constructSetter(typeBuilder, leafName, leafDesc, returnType); } return true; } @@ -782,8 +771,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { return false; } - private boolean resolveLeafSchemaNodeAsProperty( - final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, + private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, boolean isReadOnly) { if ((leaf != null) && (toBuilder != null)) { final String leafName = leaf.getQName().getLocalName(); @@ -796,12 +784,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { final TypeDefinition typeDef = leaf.getType(); // TODO: properly resolve enum types - final Type returnType = typeProvider - .javaTypeForSchemaDefinitionType(typeDef); + final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); if (returnType != null) { - final GeneratedPropertyBuilder propBuilder = toBuilder - .addProperty(parseToClassName(leafName)); + final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName)); propBuilder.setReadOnly(isReadOnly); propBuilder.setReturnType(returnType); @@ -818,9 +804,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { return false; } - private boolean resolveLeafListSchemaNode( - final GeneratedTypeBuilder typeBuilder, - final LeafListSchemaNode node) { + private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) { if ((node != null) && (typeBuilder != null)) { final String nodeName = node.getQName().getLocalName(); String nodeDesc = node.getDescription(); @@ -830,8 +814,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (nodeName != null) { final TypeDefinition type = node.getType(); - final Type listType = Types.listTypeFor(typeProvider - .javaTypeForSchemaDefinitionType(type)); + final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type)); constructGetter(typeBuilder, nodeName, nodeDesc, listType); if (!node.isConfiguration()) { @@ -843,19 +826,16 @@ public final class BindingGeneratorImpl implements BindingGenerator { return false; } - private boolean resolveContainerSchemaNode(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, + private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, final ContainerSchemaNode containerNode) { if ((containerNode != null) && (typeBuilder != null)) { final String nodeName = containerNode.getQName().getLocalName(); if (nodeName != null) { - final String packageName = packageNameForGeneratedType( - basePackageName, containerNode.getPath()); + final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); - final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition( - packageName, containerNode); - constructGetter(typeBuilder, nodeName, "", rawGenType); + final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); + constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType); return true; } @@ -863,22 +843,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { return false; } - private boolean resolveListSchemaNode(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, + private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, final ListSchemaNode schemaNode) { if ((schemaNode != null) && (typeBuilder != null)) { final String listName = schemaNode.getQName().getLocalName(); if (listName != null) { - final String packageName = packageNameForGeneratedType( - basePackageName, schemaNode.getPath()); - final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition( - packageName, schemaNode); - constructGetter(typeBuilder, listName, "", - Types.listTypeFor(rawGenType)); + final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath()); + final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode); + constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType)); if (!schemaNode.isConfiguration()) { - constructSetter(typeBuilder, listName, "", - Types.listTypeFor(rawGenType)); + constructSetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType)); } return true; } @@ -886,43 +861,66 @@ public final class BindingGeneratorImpl implements BindingGenerator { return false; } - private GeneratedTypeBuilder addRawInterfaceDefinition( - final String packageName, final SchemaNode schemaNode) { + /** + * Method instantiates new Generated Type Builder and sets the implements definitions of Data Object and + * Augmentable. + * + * @param packageName Generated Type Package Name + * @param schemaNode Schema Node definition + * @return Generated Type Builder instance for Schema Node definition + */ + private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { + final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, ""); + builder.addImplementsType(Types.DATA_OBJECT); + builder.addImplementsType(Types.augmentableTypeFor(builder)); + return builder; + } + + /** + * + * @param packageName + * @param schemaNode + * @return + */ + private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { return addRawInterfaceDefinition(packageName, schemaNode, ""); } - private GeneratedTypeBuilder addRawInterfaceDefinition( - final String packageName, final SchemaNode schemaNode, + private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode, final String prefix) { if (schemaNode == null) { - return null; + throw new IllegalArgumentException("Data Schema Node cannot be NULL!"); + } + if (packageName == null) { + throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); + } + if (schemaNode.getQName() == null) { + throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!"); } - final String schemaNodeName = schemaNode.getQName().getLocalName(); + if (schemaNodeName == null) { + throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!"); + } - if ((packageName != null) && (schemaNodeName != null)) { - final String genTypeName = prefix + parseToClassName(schemaNodeName) - ; - final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl( - packageName, genTypeName); - - newType.addImplementsType(Types.DATA_OBJECT); - newType.addImplementsType(Types.augmentableTypeFor(newType)); + final String genTypeName; + if (prefix == null) { + genTypeName = parseToClassName(schemaNodeName); + } else { + genTypeName = prefix + parseToClassName(schemaNodeName); + } - if (!genTypeBuilders.containsKey(packageName)) { - final Map builders = new HashMap<>(); + final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + if (!genTypeBuilders.containsKey(packageName)) { + final Map builders = new HashMap<>(); + builders.put(genTypeName, newType); + genTypeBuilders.put(packageName, builders); + } else { + final Map builders = genTypeBuilders.get(packageName); + if (!builders.containsKey(genTypeName)) { builders.put(genTypeName, newType); - genTypeBuilders.put(packageName, builders); - } else { - final Map builders = genTypeBuilders - .get(packageName); - if (!builders.containsKey(genTypeName)) { - builders.put(genTypeName, newType); - } } - return newType; } - return null; + return newType; } private String getterMethodName(final String methodName) { @@ -939,12 +937,9 @@ public final class BindingGeneratorImpl implements BindingGenerator { return method.toString(); } - private MethodSignatureBuilder constructGetter( - final GeneratedTypeBuilder interfaceBuilder, - final String schemaNodeName, final String comment, - final Type returnType) { - final MethodSignatureBuilder getMethod = interfaceBuilder - .addMethod(getterMethodName(schemaNodeName)); + private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder, + final String schemaNodeName, final String comment, final Type returnType) { + final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName)); getMethod.setComment(comment); getMethod.setReturnType(returnType); @@ -952,39 +947,29 @@ public final class BindingGeneratorImpl implements BindingGenerator { return getMethod; } - private MethodSignatureBuilder constructSetter( - final GeneratedTypeBuilder interfaceBuilder, - final String schemaNodeName, final String comment, - final Type parameterType) { - final MethodSignatureBuilder setMethod = interfaceBuilder - .addMethod(setterMethodName(schemaNodeName)); + private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder, + final String schemaNodeName, final String comment, final Type parameterType) { + final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName)); setMethod.setComment(comment); - setMethod.addParameter(parameterType, - parseToValidParamName(schemaNodeName)); + setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName)); setMethod.setReturnType(Types.voidType()); return setMethod; } - private List listToGenType(final String basePackageName, - final ListSchemaNode list) { + private List listToGenType(final String basePackageName, final ListSchemaNode list) { if (basePackageName == null) { - throw new IllegalArgumentException( - "Package Name for Generated Type cannot be NULL!"); + throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); } if (list == null) { - throw new IllegalArgumentException( - "List Schema Node cannot be NULL!"); + throw new IllegalArgumentException("List Schema Node cannot be NULL!"); } - final String packageName = packageNameForGeneratedType(basePackageName, - list.getPath()); - final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder( - packageName, list); + final String packageName = packageNameForGeneratedType(basePackageName, list.getPath()); + final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list); final List listKeys = listKeys(list); - GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, - list, listKeys); + GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys); final Set schemaNodes = list.getChildNodes(); @@ -992,24 +977,19 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (schemaNode.isAugmenting()) { continue; } - addSchemaNodeToListBuilders(basePackageName, schemaNode, - typeBuilder, genTOBuilder, listKeys); + addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); } return typeBuildersToGenTypes(typeBuilder, genTOBuilder); } - private void addSchemaNodeToListBuilders(final String basePackageName, - final DataSchemaNode schemaNode, - final GeneratedTypeBuilder typeBuilder, - final GeneratedTOBuilder genTOBuilder, final List listKeys) { + private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode, + final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys) { if (schemaNode == null) { - throw new IllegalArgumentException( - "Data Schema Node cannot be NULL!"); + throw new IllegalArgumentException("Data Schema Node cannot be NULL!"); } if (typeBuilder == null) { - throw new IllegalArgumentException( - "Generated Type Builder cannot be NULL!"); + throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); } if (schemaNode instanceof LeafSchemaNode) { @@ -1020,30 +1000,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); } } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, - (LeafListSchemaNode) schemaNode); + resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, - (ContainerSchemaNode) schemaNode); + resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, - (ListSchemaNode) schemaNode); + resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); } } - private List typeBuildersToGenTypes( - final GeneratedTypeBuilder typeBuilder, - GeneratedTOBuilder genTOBuilder) { + private List typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { final List genTypes = new ArrayList<>(); if (typeBuilder == null) { - throw new IllegalArgumentException( - "Generated Type Builder cannot be NULL!"); + throw new IllegalArgumentException("Generated Type Builder cannot be NULL!"); } if (genTOBuilder != null) { final GeneratedTransferObject genTO = genTOBuilder.toInstance(); - constructGetter(typeBuilder, genTO.getName(), - "Returns Primary Key of Yang List Type", genTO); + constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO); genTypes.add(genTO); } genTypes.add(typeBuilder.toInstance()); @@ -1054,14 +1027,12 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param list * @return */ - private GeneratedTOBuilder resolveListKey(final String packageName, - final ListSchemaNode list) { + private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) { final String listName = list.getQName().getLocalName() + "Key"; return schemaNodeToTransferObjectBuilder(packageName, list, listName); } - private boolean isPartOfListKey(final LeafSchemaNode leaf, - final List keys) { + private boolean isPartOfListKey(final LeafSchemaNode leaf, final List keys) { if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) { final String leafName = leaf.getQName().getLocalName(); if (keys.contains(leafName)) { @@ -1084,34 +1055,29 @@ public final class BindingGeneratorImpl implements BindingGenerator { return listKeys; } - private GeneratedTypeBuilder resolveListTypeBuilder( - final String packageName, final ListSchemaNode list) { + private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) { if (packageName == null) { - throw new IllegalArgumentException( - "Package Name for Generated Type cannot be NULL!"); + throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!"); } if (list == null) { - throw new IllegalArgumentException( - "List Schema Node cannot be NULL!"); + throw new IllegalArgumentException("List Schema Node cannot be NULL!"); } final String schemaNodeName = list.getQName().getLocalName(); final String genTypeName = parseToClassName(schemaNodeName); GeneratedTypeBuilder typeBuilder = null; - final Map builders = genTypeBuilders - .get(packageName); + final Map builders = genTypeBuilders.get(packageName); if (builders != null) { typeBuilder = builders.get(genTypeName); } if (typeBuilder == null) { - typeBuilder = addRawInterfaceDefinition(packageName, list); + typeBuilder = addDefaultInterfaceDefinition(packageName, list); } return typeBuilder; } - private GeneratedTOBuilder resolveListKeyTOBuilder( - final String packageName, final ListSchemaNode list, + private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list, final List listKeys) { GeneratedTOBuilder genTOBuilder = null; if (listKeys.size() > 0) { diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java new file mode 100644 index 0000000000..e800b5b8c7 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java @@ -0,0 +1,60 @@ +/* + * 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.sal.binding.generator.impl; + +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.model.api.Type; +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; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +public class ChoiceCaseGenTypesTest { + + private final static List yangModels = new ArrayList<>(); + private final static String yangModelsFolder = AugmentedTypeTest.class.getResource("/choice-case-type-test-models") + .getPath(); + + @BeforeClass + public static void loadTestResources() { + final File augFolder = new File(yangModelsFolder); + for (final File fileEntry : augFolder.listFiles()) { + if (fileEntry.isFile()) { + yangModels.add(fileEntry); + } + } + } + + @Test + public void choiceCaseResolvingTypeTest() { + final YangModelParser parser = new YangParserImpl(); + final Set modules = parser.parseYangModels(yangModels); + final SchemaContext context = parser.resolveSchemaContext(modules); + + assertNotNull("context is null", context); + final BindingGenerator bindingGen = new BindingGeneratorImpl(); + final List genTypes = bindingGen.generateTypes(context); + + assertNotNull("genTypes is null", genTypes); + assertFalse("genTypes is empty", genTypes.isEmpty()); + + //Expected 23 types from ietf-netconf-monitoring + //Expected 14 types from ietf-yang-types + //Expected 14 types from ietf-inet-types + } +} diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang new file mode 100644 index 0000000000..17cf07c49a --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang @@ -0,0 +1,88 @@ +module augment-monitoring { + yang-version 1; + namespace "urn:ietf:params:xml:ns:yang:augment-monitoring"; + prefix "amon"; + + import ietf-netconf-monitoring { prefix nm; } + + organization "OPEN DAYLIGHT"; + contact "http://www.opendaylight.org/"; + + revision "2013-07-01" { + reference "NO REF"; + } + + augment "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type" { + case autonomous-lock { + container autonomous-def { + leaf lock-id { + type int32; + } + + leaf lock-time { + type uint32; + } + } + } + + case anonymous-lock { + leaf lock-time { + type uint32; + } + } + + leaf leaf-aug-case { + type string; + } + } + + augment "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type/nm:partial-lock" { + choice aug-case-by-choice { + case foo { + leaf foo { + type string; + } + } + + case bar { + leaf bar { + type boolean; + } + } + } + } + + augment "/nm:netconf-state/nm:datastores/nm:datastore" { + choice storage-format { + case xml { + container xml-def { + leaf file-name { + type string; + } + } + } + + case yang { + leaf yang-file-name { + type string; + } + } + + case unknown-files { + list files { + key "file-name"; + + leaf file-name { + type string; + } + + container file-data { + leaf utf8-data { + type string; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-inet-types@2010-09-24.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-inet-types@2010-09-24.yang new file mode 100644 index 0000000000..de20febbb7 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-inet-types@2010-09-24.yang @@ -0,0 +1,418 @@ + module ietf-inet-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Partain + + + WG Chair: David Kessens + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + + Copyright (c) 2010 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in Section + 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6021; see + the RFC itself for full legal notices."; + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of protocol field related types ***/ + + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code-Point + that may be used for marking packets in a traffic stream. + + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The flow-label type represents flow identifier or Flow Label + in an IPv6 packet header that may be used to discriminate + traffic flows. + + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of autonomous system related types ***/ + + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASs'. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4893: BGP Support for Four-octet AS Number Space + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of IP address and hostname related types ***/ + + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format for the zone index is the numerical + format"; + } + + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format of IPv6 addresses uses the compressed + format described in RFC 4291, Section 2.2, item 2 with the + following additional rules: the :: substitution must be + applied to the longest sequence of all-zero 16-bit chunks + in an IPv6 address. If there is a tie, the first sequence + of all-zero 16-bit chunks is replaced by ::. Single + all-zero 16-bit chunks are not compressed. The canonical + format uses lowercase characters and leading zeros are + not allowed. The canonical format for the zone index is + the numerical format as described in RFC 4007, Section + 11.2."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text Representation"; + } + + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal 128. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, IPv6 address is represented + in the compressed format described in RFC 4291, Section + 2.2, item 2 with the following additional rules: the :: + substitution must be applied to the longest sequence of + all-zero 16-bit chunks in an IPv6 address. If there is + a tie, the first sequence of all-zero 16-bit chunks is + replaced by ::. Single all-zero 16-bit chunks are not + compressed. The canonical format uses lowercase + characters and leading zeros are not allowed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture"; + } + + /*** collection of domain name and URI types ***/ + + typedef domain-name { + type string { + pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + length "1..253"; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitely or it may depend on the configuration of the + resolver. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be encoded in punycode as described in RFC + 3492"; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 3492: Punycode: A Bootstring encoding of Unicode for + Internationalized Domain Names in Applications + (IDNA) + RFC 5891: Internationalizing Domain Names in Applications + (IDNA): Protocol"; + } + + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } + + } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang new file mode 100644 index 0000000000..695fb1dd38 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang @@ -0,0 +1,254 @@ +module ietf-netconf-monitoring { + + namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"; + prefix "ncm"; + + import ietf-yang-types { prefix yang; } + import ietf-inet-types { prefix inet; } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: Mehmet Ersue + + + WG Chair: Bert Wijnen + + + Editor: Mark Scott + + + Editor: Martin Bjorklund + "; + + description + "NETCONF Monitoring Module. + All elements in this module are read-only. + + Copyright (c) 2010 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6022; see + the RFC itself for full legal notices."; + + revision 2010-10-04 { + description + "Initial revision."; + reference + "RFC 6022: YANG Module for NETCONF Monitoring"; + } + + typedef tls-fingerprint-type { + type string { + pattern '([0-9a-fA-F]){2}(:([0-9a-fA-F]){2})*'; + } + description + "A cryptographic signature (fingerprint) value that can be used to + uniquely reference other data of potentially arbitrary length."; + } + + typedef netconf-datastore-type { + type enumeration { + enum running; + enum candidate; + enum startup; + } + description + "Enumeration of possible NETCONF datastore types."; + reference + "RFC 4741: NETCONF Configuration Protocol"; + } + + container netconf-state { + config false; + description + "The netconf-state container is the root of the monitoring + data model."; + + container datastores { + description + "Contains the list of NETCONF configuration datastores."; + + list datastore { + key name; + description + "List of NETCONF configuration datastores supported by + the NETCONF server and related information."; + + leaf name { + type netconf-datastore-type; + description + "Name of the datastore associated with this list entry."; + } + container locks { + presence + "This container is present only if the datastore + is locked."; + description + "The NETCONF and operations allow + a client to lock specific resources in a datastore. The + NETCONF server will prevent changes to the locked + resources by all sessions except the one that acquired + the lock(s). + + Monitoring information is provided for each datastore + entry including details such as the session that acquired + the lock, the type of lock (global or partial) and the + list of locked resources. Multiple locks per datastore + are supported."; + + choice lock-type { + description + "Indicates if a global lock or a set of partial locks + are set."; + + case global-lock { + container global-lock { + description + "Present if the global lock is set."; + + leaf locked-by-session { + type uint32; + mandatory true; + description + "The session ID of the session that has locked + this resource. Both a global lock and a partial + lock MUST contain the NETCONF session-id. + + If the lock is held by a session that is not managed + by the NETCONF server (e.g., a CLI session), a session + id of 0 (zero) is reported."; + reference + "RFC 4741: NETCONF Configuration Protocol"; + } + leaf locked-time { + type yang:date-and-time; + mandatory true; + description + "The date and time of when the resource was + locked."; + } + + container capabilities { + description + "Contains the list of NETCONF capabilities supported by the + server."; + + leaf-list capability { + type inet:uri; + description + "List of NETCONF capabilities supported by the server."; + } + } + } + } + + case partial-lock { + list partial-lock { + key lock-id; + description + "List of partial locks."; + reference + "RFC 5717: Partial Lock Remote Procedure Call (RPC) for + NETCONF"; + + leaf lock-id { + type uint32; + description + "This is the lock id returned in the + response."; + } + leaf-list select { + type yang:xpath1.0; + min-elements 1; + description + "The xpath expression that was used to request + the lock. The select expression indicates the + original intended scope of the lock."; + } + leaf-list locked-node { + type string; + description + "The list of instance-identifiers (i.e., the + locked nodes). The scope of the partial lock is defined by the list + of locked nodes."; + } + } + } + + case fingerprint { + choice algorithm-and-hash { + mandatory true; + case md5 { + leaf md5 { + type tls-fingerprint-type; + } + } + + case sha1 { + leaf sha1 { + type tls-fingerprint-type; + } + } + + case sha224 { + leaf sha224 { + type tls-fingerprint-type; + } + } + + case sha256 { + leaf sha256 { + type tls-fingerprint-type; + } + } + + case sha384 { + leaf sha384 { + type tls-fingerprint-type; + } + } + + case sha512 { + leaf sha512 { + type tls-fingerprint-type; + } + } + + description + "Specifies the signature algorithm and cryptographic + signature (fingerprint) used to identify an X.509 + certificate. + + Implementations of this YANG module MAY, but are not + required to, implement all of these cryptographic signature + algorithms. Implementations of this YANG module MUST + implement at least one of these cryptographic signature + algorithms. + + The available choices may be extended in the future as + stronger cryptographic signature algorithms become + available and are deemed necessary."; + + reference + "RFC 5246: The Transport Layer Security (TLS) Protocol + Version 1.2; Section 7.4.1.4.1, Signature Algorithms"; + } // choice algorithm-and-hash + } + } + } + } + } + } +} diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-yang-types@2010-09-24.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-yang-types@2010-09-24.yang new file mode 100644 index 0000000000..e9d88ab781 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-yang-types@2010-09-24.yang @@ -0,0 +1,396 @@ + module ietf-yang-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types"; + prefix "yang"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Partain + + + WG Chair: David Kessens + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types. + + Copyright (c) 2010 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in Section + 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6021; see + the RFC itself for full legal notices."; + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of counter and gauge types ***/ + + typedef counter32 { + type uint32; + description + "The counter32 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter32 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter32 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter32. + + In the value set and its semantics, this type is equivalent + to the Counter32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef zero-based-counter32 { + type yang:counter32; + default "0"; + description + "The zero-based-counter32 type represents a counter32 + that has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter32 textual convention of the SMIv2."; + reference + "RFC 4502: Remote Network Monitoring Management Information + Base Version 2"; + } + + typedef counter64 { + type uint64; + description + "The counter64 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter64 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter64 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter64. + + In the value set and its semantics, this type is equivalent + to the Counter64 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef zero-based-counter64 { + type yang:counter64; + default "0"; + description + "The zero-based-counter64 type represents a counter64 that + has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter64 textual convention of the SMIv2."; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + typedef gauge32 { + type uint32; + description + "The gauge32 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^32-1 (4294967295 decimal), and + the minimum value cannot be smaller than 0. The value of + a gauge32 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge32 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the Gauge32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef gauge64 { + type uint64; + description + "The gauge64 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^64-1 (18446744073709551615), and + the minimum value cannot be smaller than 0. The value of + a gauge64 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge64 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the CounterBasedGauge64 SMIv2 textual convention defined + in RFC 2856"; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + /*** collection of identifier related types ***/ + + typedef object-identifier { + type string { + pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))' + + '(\.(0|([1-9]\d*)))*'; + } + description + "The object-identifier type represents administratively + assigned names in a registration-hierarchical-name tree. + + Values of this type are denoted as a sequence of numerical + non-negative sub-identifier values. Each sub-identifier + value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers + are separated by single dots and without any intermediate + whitespace. + + The ASN.1 standard restricts the value space of the first + sub-identifier to 0, 1, or 2. Furthermore, the value space + of the second sub-identifier is restricted to the range + 0 to 39 if the first sub-identifier is 0 or 1. Finally, + the ASN.1 standard requires that an object identifier + has always at least two sub-identifier. The pattern + captures these restrictions. + + Although the number of sub-identifiers is not limited, + module designers should realize that there may be + implementations that stick with the SMIv2 limit of 128 + sub-identifiers. + + This type is a superset of the SMIv2 OBJECT IDENTIFIER type + since it is not restricted to 128 sub-identifiers. Hence, + this type SHOULD NOT be used to represent the SMIv2 OBJECT + IDENTIFIER type, the object-identifier-128 type SHOULD be + used instead."; + reference + "ISO9834-1: Information technology -- Open Systems + Interconnection -- Procedures for the operation of OSI + Registration Authorities: General procedures and top + arcs of the ASN.1 Object Identifier tree"; + } + + + + + typedef object-identifier-128 { + type object-identifier { + pattern '\d*(\.\d*){1,127}'; + } + description + "This type represents object-identifiers restricted to 128 + sub-identifiers. + + In the value set and its semantics, this type is equivalent + to the OBJECT IDENTIFIER type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + /*** collection of date and time related types ***/ + + typedef date-and-time { + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + + '(Z|[\+\-]\d{2}:\d{2})'; + } + description + "The date-and-time type is a profile of the ISO 8601 + standard for representation of dates and times using the + Gregorian calendar. The profile is defined by the + date-time production in Section 5.6 of RFC 3339. + + The date-and-time type is compatible with the dateTime XML + schema type with the following notable exceptions: + + (a) The date-and-time type does not allow negative years. + + (b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z all + represent the same time zone in dateTime. + + (c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using the + time-offset 'Z'. + + This type is not equivalent to the DateAndTime textual + convention of the SMIv2 since RFC 3339 uses a different + separator between full-date and full-time and provides + higher resolution of time-secfrac. + + The canonical format for date-and-time values with a known time + zone uses a numeric time zone offset that is calculated using + the device's configured known offset to UTC time. A change of + the device's offset to UTC time will cause date-and-time values + to change accordingly. Such changes might happen periodically + in case a server follows automatically daylight saving time + (DST) time zone offset changes. The canonical format for + date-and-time values with an unknown time zone (usually referring + to the notion of local time) uses the time-offset -00:00."; + reference + "RFC 3339: Date and Time on the Internet: Timestamps + RFC 2579: Textual Conventions for SMIv2 + XSD-TYPES: XML Schema Part 2: Datatypes Second Edition"; + } + + typedef timeticks { + type uint32; + description + "The timeticks type represents a non-negative integer that + represents the time, modulo 2^32 (4294967296 decimal), in + hundredths of a second between two epochs. When a schema + node is defined that uses this type, the description of + the schema node identifies both of the reference epochs. + + In the value set and its semantics, this type is equivalent + to the TimeTicks type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 (SMIv2)"; + } + + typedef timestamp { + type yang:timeticks; + description + "The timestamp type represents the value of an associated + timeticks schema node at which a specific occurrence happened. + The specific occurrence must be defined in the description + of any schema node defined using this type. When the specific + occurrence occurred prior to the last time the associated + timeticks attribute was zero, then the timestamp value is + zero. Note that this requires all timestamp values to be + reset to zero when the value of the associated timeticks + attribute reaches 497+ days and wraps around to zero. + + The associated timeticks schema node must be specified + in the description of any schema node using this type. + + In the value set and its semantics, this type is equivalent + to the TimeStamp textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of generic address types ***/ + + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "Represents media- or physical-level addresses represented + as a sequence octets, each octet represented by two hexadecimal + numbers. Octets are separated by colons. The canonical + representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the PhysAddress textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + } + description + "The mac-address type represents an IEEE 802 MAC address. + The canonical representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the MacAddress textual convention of the SMIv2."; + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture + RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of XML specific types ***/ + + typedef xpath1.0 { + type string; + description + "This type represents an XPATH 1.0 expression. + + When a schema node is defined that uses this type, the + description of the schema node MUST specify the XPath + context in which the XPath expression is evaluated."; + reference + "XPATH: XML Path Language (XPath) Version 1.0"; + } + + } \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/AbstractTypeMemberBuilder.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/AbstractTypeMemberBuilder.java index 391c3afb7a..677c5e283c 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/AbstractTypeMemberBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/AbstractTypeMemberBuilder.java @@ -87,7 +87,7 @@ abstract class AbstractTypeMemberBuilder implements TypeMemberBuilder { @Override public void setComment(String comment) { if (comment == null) { - throw new IllegalArgumentException("Comment string cannot be null!"); + this.comment = ""; } this.comment = comment; } 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 b95ac48928..b8f988bff3 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 @@ -12,22 +12,15 @@ import static org.opendaylight.controller.sal.java.api.generator.Constants.*; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.opendaylight.controller.binding.generator.util.TypeConstants; -import org.opendaylight.controller.sal.binding.model.api.CodeGenerator; -import org.opendaylight.controller.sal.binding.model.api.Constant; -import org.opendaylight.controller.sal.binding.model.api.Enumeration; -import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty; -import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferIdentityObject; -import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.controller.sal.binding.model.api.Type; +import org.opendaylight.controller.sal.binding.model.api.*; public final class ClassCodeGenerator implements CodeGenerator { - private Map> imports; + private Map imports; @Override public Writer generate(Type type) throws IOException { @@ -93,26 +86,24 @@ public final class ClassCodeGenerator implements CodeGenerator { writer.write(GeneratorUtil.createSetter(field, TAB, imports, currentPkg) + NL); } } - } - writer.write(NL); + writer.write(NL); - if (!genTO.getHashCodeIdentifiers().isEmpty()) { - writer.write(GeneratorUtil.createHashCode(genTO.getHashCodeIdentifiers(), TAB) + NL); - } + if (!genTO.getHashCodeIdentifiers().isEmpty()) { + writer.write(GeneratorUtil.createHashCode(genTO.getHashCodeIdentifiers(), TAB) + NL); + } - if (!genTO.getEqualsIdentifiers().isEmpty()) { - writer.write(GeneratorUtil.createEquals(genTO, genTO.getEqualsIdentifiers(), TAB) + NL); - } + if (!genTO.getEqualsIdentifiers().isEmpty()) { + writer.write(GeneratorUtil.createEquals(genTO, genTO.getEqualsIdentifiers(), TAB) + NL); + } - if (!genTO.getToStringIdentifiers().isEmpty()) { - writer.write(GeneratorUtil.createToString(genTO, genTO.getToStringIdentifiers(), TAB) + NL); + if (!genTO.getToStringIdentifiers().isEmpty()) { + writer.write(GeneratorUtil.createToString(genTO, genTO.getToStringIdentifiers(), TAB) + NL); + } + writer.write(RCB); } - - writer.write(RCB); } } return writer; } - } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/EnumGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/EnumGenerator.java index 33d2917339..760365d171 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/EnumGenerator.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/EnumGenerator.java @@ -7,7 +7,7 @@ */ package org.opendaylight.controller.sal.java.api.generator; -import static org.opendaylight.controller.sal.java.api.generator.Constants.*; +import static org.opendaylight.controller.sal.java.api.generator.Constants.NL; import java.io.IOException; import java.io.StringWriter; @@ -19,30 +19,29 @@ import org.opendaylight.controller.sal.binding.model.api.Type; public class EnumGenerator implements CodeGenerator { - @Override - public Writer generate(Type type) throws IOException { - final Writer writer = new StringWriter(); + @Override + public Writer generate(Type type) throws IOException { + final Writer writer = new StringWriter(); - if (type instanceof Enumeration) { - Enumeration enums = (Enumeration) type; - writer.write(GeneratorUtil.createPackageDeclaration(enums - .getPackageName())); - writer.write(NL + NL); - writer.write(GeneratorUtil.createEnum(enums, "")); - } + if (type instanceof Enumeration) { + Enumeration enums = (Enumeration) type; + writer.write(GeneratorUtil.createPackageDeclaration(enums.getPackageName())); + writer.write(NL + NL); + writer.write(GeneratorUtil.createEnum(enums, "")); + } - return writer; - } + return writer; + } - public Writer generateInnerEnumeration(Type type, String indent) throws IOException { - final Writer writer = new StringWriter(); + public Writer generateInnerEnumeration(Type type, String indent) throws IOException { + final Writer writer = new StringWriter(); - if (type instanceof Enumeration) { - Enumeration enums = (Enumeration) type; - writer.write(GeneratorUtil.createEnum(enums, indent)); - } + if (type instanceof Enumeration) { + Enumeration enums = (Enumeration) type; + writer.write(GeneratorUtil.createEnum(enums, indent)); + } - return writer; - } + return writer; + } } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java index ab103b471e..55b8d777b7 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java @@ -7,38 +7,28 @@ */ package org.opendaylight.controller.sal.java.api.generator; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; +import java.io.*; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.opendaylight.controller.sal.binding.model.api.CodeGenerator; -import org.opendaylight.controller.sal.binding.model.api.Enumeration; -import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.controller.sal.binding.model.api.GeneratedType; -import org.opendaylight.controller.sal.binding.model.api.Type; +import org.opendaylight.controller.sal.binding.model.api.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class GeneratorJavaFile { - private static final Logger log = LoggerFactory - .getLogger(GeneratorJavaFile.class); + private static final Logger log = LoggerFactory.getLogger(GeneratorJavaFile.class); private final CodeGenerator interfaceGenerator; private final ClassCodeGenerator classGenerator; private final EnumGenerator enumGenerator; - + private final Set genTypes; private final Set genTransferObjects; - private final Set enumerations; + private final Set enumerations; - public GeneratorJavaFile(final CodeGenerator codeGenerator, - final Set types) { + public GeneratorJavaFile(final CodeGenerator codeGenerator, final Set types) { this.interfaceGenerator = codeGenerator; this.genTypes = types; this.genTransferObjects = new HashSet<>(); @@ -47,13 +37,12 @@ public final class GeneratorJavaFile { this.enumGenerator = new EnumGenerator(); } - public GeneratorJavaFile(final Set types, - final Set genTransferObjects, + public GeneratorJavaFile(final Set types, final Set genTransferObjects, final Set enumerations) { this.interfaceGenerator = new InterfaceGenerator(); this.classGenerator = new ClassCodeGenerator(); this.enumGenerator = new EnumGenerator(); - + this.genTypes = types; this.genTransferObjects = genTransferObjects; this.enumerations = enumerations; @@ -62,52 +51,46 @@ public final class GeneratorJavaFile { public List generateToFile(final File parentDirectory) throws IOException { final List result = new ArrayList<>(); for (GeneratedType type : genTypes) { - final File genFile = generateTypeToJavaFile(parentDirectory, type, - interfaceGenerator); + final File genFile = generateTypeToJavaFile(parentDirectory, type, interfaceGenerator); if (genFile != null) { result.add(genFile); } } for (GeneratedTransferObject transferObject : genTransferObjects) { - final File genFile = generateTypeToJavaFile(parentDirectory, - transferObject, classGenerator); + final File genFile = generateTypeToJavaFile(parentDirectory, transferObject, classGenerator); if (genFile != null) { result.add(genFile); } } - + for (Enumeration enumeration : enumerations) { - final File genFile = generateTypeToJavaFile(parentDirectory, - enumeration, enumGenerator); + final File genFile = generateTypeToJavaFile(parentDirectory, enumeration, enumGenerator); if (genFile != null) { result.add(genFile); } } - + return result; } - private File generateTypeToJavaFile(final File parentDir, final Type type, - final CodeGenerator generator) throws IOException { + private File generateTypeToJavaFile(final File parentDir, final Type type, final CodeGenerator generator) + throws IOException { if (parentDir == null) { log.warn("Parent Directory not specified, files will be generated " + "accordingly to generated Type package path."); } if (type == null) { - log.error("Cannot generate Type into Java File because " + - "Generated Type is NULL!"); + log.error("Cannot generate Type into Java File because " + "Generated Type is NULL!"); throw new IllegalArgumentException("Generated Type Cannot be NULL!"); } if (generator == null) { - log.error("Cannot generate Type into Java File because " + - "Code Generator instance is NULL!"); + log.error("Cannot generate Type into Java File because " + "Code Generator instance is NULL!"); throw new IllegalArgumentException("Code Generator Cannot be NULL!"); } - final File packageDir = packageToDirectory(parentDir, - type.getPackageName()); + final File packageDir = packageToDirectory(parentDir, type.getPackageName()); if (!packageDir.exists()) { packageDir.mkdirs(); @@ -127,8 +110,7 @@ public final class GeneratorJavaFile { return file; } - private File packageToDirectory(final File parentDirectory, - final String packageName) { + private File packageToDirectory(final File parentDirectory, final String packageName) { if (packageName == null) { throw new IllegalArgumentException("Package Name cannot be NULL!"); } 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 16074c7e98..ec908560e4 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 @@ -10,25 +10,15 @@ package org.opendaylight.controller.sal.java.api.generator; import static org.opendaylight.controller.sal.java.api.generator.Constants.*; import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; 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.AnnotationType; -import org.opendaylight.controller.sal.binding.model.api.Constant; -import org.opendaylight.controller.sal.binding.model.api.Enumeration; import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair; -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.GeneratedType; -import org.opendaylight.controller.sal.binding.model.api.MethodSignature; import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter; -import org.opendaylight.controller.sal.binding.model.api.ParameterizedType; -import org.opendaylight.controller.sal.binding.model.api.Type; -import org.opendaylight.controller.sal.binding.model.api.WildcardType; public final class GeneratorUtil { @@ -36,12 +26,12 @@ public final class GeneratorUtil { } public static String createIfcDeclaration(final GeneratedType genType, final String indent, - final Map> availableImports) { + final Map availableImports) { return createFileDeclaration(IFC, genType, indent, availableImports, false); } public static String createClassDeclaration(final GeneratedTransferObject genTransferObject, final String indent, - final Map> availableImports, boolean isIdentity) { + final Map availableImports, boolean isIdentity) { return createFileDeclaration(CLASS, genTransferObject, indent, availableImports, isIdentity); } @@ -50,7 +40,7 @@ public final class GeneratorUtil { } private static String createFileDeclaration(final String type, final GeneratedType genType, final String indent, - final Map> availableImports, boolean isIdentity) { + final Map availableImports, boolean isIdentity) { final StringBuilder builder = new StringBuilder(); final String currentPkg = genType.getPackageName(); @@ -95,7 +85,6 @@ public final class GeneratorUtil { builder.append(getExplicitType(genImplements.get(i), availableImports, currentPkg)); } } - builder.append(GAP + LCB); return builder.toString(); } @@ -153,7 +142,7 @@ public final class GeneratorUtil { } public static String createConstant(final Constant constant, final String indent, - final Map> availableImports, final String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); if (constant == null) throw new IllegalArgumentException(); @@ -189,7 +178,7 @@ public final class GeneratorUtil { } public static String createField(final GeneratedProperty property, final String indent, - Map> availableImports, final String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); if (!property.getAnnotations().isEmpty()) { final List annotations = property.getAnnotations(); @@ -211,7 +200,7 @@ public final class GeneratorUtil { * @return */ public static String createMethodDeclaration(final MethodSignature method, final String indent, - Map> availableImports, final String currentPkg) { + Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); if (method == null) { @@ -258,7 +247,7 @@ public final class GeneratorUtil { } public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent, - Map> availableImports, boolean isIdentity) { + final Map availableImports, boolean isIdentity) { final StringBuilder builder = new StringBuilder(); final String currentPkg = genTransferObject.getPackageName(); @@ -333,7 +322,7 @@ public final class GeneratorUtil { } public static String createGetter(final GeneratedProperty property, final String indent, - Map> availableImports, final String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); final Type type = property.getReturnType(); @@ -353,7 +342,7 @@ public final class GeneratorUtil { } public static String createSetter(final GeneratedProperty property, final String indent, - Map> availableImports, String currentPkg) { + final Map availableImports, final String currentPkg) { final StringBuilder builder = new StringBuilder(); final Type type = property.getReturnType(); @@ -388,7 +377,7 @@ public final class GeneratorUtil { public static String createEquals(final GeneratedTransferObject type, final List properties, final String indent) { - StringBuilder builder = new StringBuilder(); + final StringBuilder builder = new StringBuilder(); final String indent1 = indent + TAB; final String indent2 = indent1 + TAB; final String indent3 = indent2 + TAB; @@ -407,7 +396,7 @@ public final class GeneratorUtil { String typeStr = type.getName(); builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" + NL); - for (GeneratedProperty property : properties) { + for (final GeneratedProperty property : properties) { String fieldName = property.getName(); builder.append(indent1 + "if (" + fieldName + " == null) {" + NL); builder.append(indent2 + "if (other." + fieldName + " != null) {" + NL); @@ -419,7 +408,6 @@ public final class GeneratorUtil { } builder.append(indent1 + "return true;" + NL); - builder.append(indent + RCB + NL); return builder.toString(); } @@ -441,7 +429,7 @@ public final class GeneratorUtil { builder.append(" ["); boolean first = true; - for (GeneratedProperty property : properties) { + for (final GeneratedProperty property : properties) { if (first) { builder.append(property.getName()); builder.append("=\");"); @@ -514,22 +502,30 @@ public final class GeneratorUtil { return builder.toString(); } - private static String getExplicitType(final Type type, - Map> availableImports, final String currentPkg) { + private static String getExplicitType(final Type type, final Map imports, final String currentPkg) { if (type == null) { throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); } - String packageName = type.getPackageName(); - - LinkedHashMap imports = availableImports.get(type.getName()); + if (type.getName() == null) { + throw new IllegalArgumentException("Type name cannot be NULL!"); + } + if (type.getPackageName() == null) { + throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); + } + if (imports == null) { + throw new IllegalArgumentException("Imports Map cannot be NULL!"); + } - if ((imports != null && packageName.equals(findMaxValue(imports).get(0))) || packageName.equals(currentPkg)) { + final String typePackageName = type.getPackageName(); + final String typeName = type.getName(); + final String importedPackageName = imports.get(typeName); + if (typePackageName.equals(importedPackageName) || typePackageName.equals(currentPkg)) { final StringBuilder builder = new StringBuilder(type.getName()); if (type instanceof ParameterizedType) { - ParameterizedType pType = (ParameterizedType) type; - Type[] pTypes = pType.getActualTypeArguments(); + final ParameterizedType pType = (ParameterizedType) type; + final Type[] pTypes = pType.getActualTypeArguments(); builder.append("<"); - builder.append(getParameters(pTypes, availableImports, currentPkg)); + builder.append(getParameters(pTypes, imports, currentPkg)); builder.append(">"); } if (builder.toString().equals("Void")) { @@ -538,21 +534,20 @@ public final class GeneratorUtil { return builder.toString(); } else { final StringBuilder builder = new StringBuilder(); - if (packageName.startsWith("java.lang")) { + if (typePackageName.startsWith("java.lang")) { builder.append(type.getName()); } else { - if (!packageName.isEmpty()) { - builder.append(packageName + "." + type.getName()); + if (!typePackageName.isEmpty()) { + builder.append(typePackageName + "." + type.getName()); } else { builder.append(type.getName()); } - } if (type instanceof ParameterizedType) { - ParameterizedType pType = (ParameterizedType) type; - Type[] pTypes = pType.getActualTypeArguments(); + final ParameterizedType pType = (ParameterizedType) type; + final Type[] pTypes = pType.getActualTypeArguments(); builder.append("<"); - builder.append(getParameters(pTypes, availableImports, currentPkg)); + builder.append(getParameters(pTypes, imports, currentPkg)); builder.append(">"); } if (builder.toString().equals("Void")) { @@ -562,14 +557,13 @@ public final class GeneratorUtil { } } - private static String getParameters(final Type[] pTypes, - Map> availableImports, String currentPkg) { + private static String getParameters(final Type[] pTypes, Map availableImports, String currentPkg) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < pTypes.length; i++) { - Type t = pTypes[i]; + final Type t = pTypes[i]; String separator = COMMA; - if (i + 1 == pTypes.length) { + if (i == (pTypes.length - 1)) { separator = ""; } @@ -577,30 +571,11 @@ public final class GeneratorUtil { if (t instanceof WildcardType) { wildcardParam = "? extends "; } - builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + separator); } return builder.toString(); } - private static List findMaxValue(LinkedHashMap imports) { - final List result = new ArrayList(); - - int maxValue = 0; - int currentValue = 0; - for (Map.Entry entry : imports.entrySet()) { - currentValue = entry.getValue(); - if (currentValue > maxValue) { - result.clear(); - result.add(entry.getKey()); - maxValue = currentValue; - } else if (currentValue == maxValue) { - result.add(entry.getKey()); - } - } - return result; - } - private static void createComment(final StringBuilder builder, final String comment, final String indent) { if (comment != null && comment.length() > 0) { builder.append(indent + "/*" + NL); @@ -609,104 +584,115 @@ public final class GeneratorUtil { } } - public static Map> createImports(GeneratedType genType) { - final Map> imports = new HashMap>(); - final String genTypePkg = genType.getPackageName(); + public static Map createImports(final GeneratedType genType) { + if (genType == null) { + throw new IllegalArgumentException("Generated Type cannot be NULL!"); + } + final Map imports = new LinkedHashMap<>(); final List constants = genType.getConstantDefinitions(); final List methods = genType.getMethodDefinitions(); - List impl = genType.getImplements(); + final List impl = genType.getImplements(); // IMPLEMENTATIONS if (impl != null) { - for (Type t : impl) { - addTypeToImports(t, imports, genTypePkg); + for (final Type type : impl) { + putTypeIntoImports(genType, type, imports); } } // CONSTANTS if (constants != null) { - for (Constant c : constants) { - Type ct = c.getType(); - addTypeToImports(ct, imports, genTypePkg); + for (final Constant constant : constants) { + final Type constantType = constant.getType(); + putTypeIntoImports(genType, constantType, imports); + } + } + + // REGULAR EXPRESSION + if (genType instanceof GeneratedTransferObject) { + if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { + putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports); + putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports); + putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports); } } // METHODS if (methods != null) { - for (MethodSignature m : methods) { - Type ct = m.getReturnType(); - addTypeToImports(ct, imports, genTypePkg); - for (MethodSignature.Parameter p : m.getParameters()) { - addTypeToImports(p.getType(), imports, genTypePkg); + for (final MethodSignature method : methods) { + final Type methodReturnType = method.getReturnType(); + putTypeIntoImports(genType, methodReturnType, imports); + for (final MethodSignature.Parameter methodParam : method.getParameters()) { + putTypeIntoImports(genType, methodParam.getType(), imports); } } } // PROPERTIES if (genType instanceof GeneratedTransferObject) { - GeneratedTransferObject genTO = (GeneratedTransferObject) genType; - - List props = genTO.getProperties(); - if (props != null) { - for (GeneratedProperty prop : props) { - Type pt = prop.getReturnType(); - addTypeToImports(pt, imports, genTypePkg); + final GeneratedTransferObject genTO = (GeneratedTransferObject) genType; + final List properties = genTO.getProperties(); + if (properties != null) { + for (GeneratedProperty property : properties) { + final Type propertyType = property.getReturnType(); + putTypeIntoImports(genType, propertyType, imports); } } } - // REGULAR EXPRESSION - if (genType instanceof GeneratedTransferObject) { - if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) { - addTypeToImports(Types.typeForClass(java.util.regex.Pattern.class), imports, genTypePkg); - addTypeToImports(Types.typeForClass(java.util.Arrays.class), imports, genTypePkg); - addTypeToImports(Types.typeForClass(java.util.ArrayList.class), imports, genTypePkg); - } - } - return imports; } - private static void addTypeToImports(Type type, Map> importedTypes, - String genTypePkg) { - String typeName = type.getName(); - String typePkg = type.getPackageName(); - if (typePkg.startsWith("java.lang") || typePkg.equals(genTypePkg) || typePkg.isEmpty()) { - return; + private static void putTypeIntoImports(final GeneratedType parentGenType, final Type type, + final Map imports) { + if (parentGenType == null) { + throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be " + + "NULL!"); } - LinkedHashMap packages = importedTypes.get(typeName); - if (packages == null) { - packages = new LinkedHashMap(); - packages.put(typePkg, 1); - importedTypes.put(typeName, packages); - } else { - Integer occurrence = packages.get(typePkg); - if (occurrence == null) { - packages.put(typePkg, 1); - } else { - occurrence++; - packages.put(typePkg, occurrence); - } + if (parentGenType.getName() == null) { + throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!"); + } + if (parentGenType.getPackageName() == null) { + throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!"); + } + if (type == null) { + throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!"); + } + if (type.getName() == null) { + throw new IllegalArgumentException("Type name cannot be NULL!"); + } + if (type.getPackageName() == null) { + throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!"); } + final String typeName = type.getName(); + final String typePackageName = type.getPackageName(); + final String parentTypeName = parentGenType.getName(); + final String parentTypePackageName = parentGenType.getPackageName(); + if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang") + || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) { + return; + } + if (!imports.containsKey(typeName)) { + imports.put(typeName, typePackageName); + } if (type instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) type; - Type[] params = pt.getActualTypeArguments(); + final ParameterizedType paramType = (ParameterizedType) type; + final Type[] params = paramType.getActualTypeArguments(); for (Type param : params) { - addTypeToImports(param, importedTypes, genTypePkg); + putTypeIntoImports(parentGenType, param, imports); } } } - public static List createImportLines(Map> imports) { - List importLines = new ArrayList(); + public static List createImportLines(final Map imports) { + final List importLines = new ArrayList<>(); - for (Map.Entry> entry : imports.entrySet()) { - String typeName = entry.getKey(); - LinkedHashMap typePkgMap = entry.getValue(); - String typePkg = typePkgMap.keySet().iterator().next(); - importLines.add("import " + typePkg + "." + typeName + SC); + for (Map.Entry entry : imports.entrySet()) { + final String typeName = entry.getKey(); + final String packageName = entry.getValue(); + importLines.add("import " + packageName + "." + typeName + SC); } return importLines; } @@ -723,5 +709,4 @@ public final class GeneratorUtil { } return false; } - } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java index 16d63efe1b..fe0b24f890 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java @@ -12,97 +12,81 @@ import static org.opendaylight.controller.sal.java.api.generator.Constants.*; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.opendaylight.controller.sal.binding.model.api.CodeGenerator; -import org.opendaylight.controller.sal.binding.model.api.Constant; -import org.opendaylight.controller.sal.binding.model.api.Enumeration; -import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.controller.sal.binding.model.api.GeneratedType; -import org.opendaylight.controller.sal.binding.model.api.MethodSignature; -import org.opendaylight.controller.sal.binding.model.api.Type; +import org.opendaylight.controller.sal.binding.model.api.*; public final class InterfaceGenerator implements CodeGenerator { - private Map> imports; + private Map imports; - private String generateEnums(List enums) { - String result = ""; - if (enums != null) { - EnumGenerator enumGenerator = new EnumGenerator(); - for (Enumeration en : enums) { - try { - result = result - + (enumGenerator.generateInnerEnumeration(en, TAB).toString() + NL); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return result; - } + private String generateEnums(List enums) { + String result = ""; + if (enums != null) { + EnumGenerator enumGenerator = new EnumGenerator(); + for (Enumeration en : enums) { + try { + result = result + (enumGenerator.generateInnerEnumeration(en, TAB).toString() + NL); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } - private String generateConstants(List constants, String pkgName) { - String result = ""; - if (constants != null) { - for (Constant c : constants) { - result = result - + GeneratorUtil - .createConstant(c, TAB, imports, pkgName) + NL; - } - result.concat(NL); - } - return result; - } + private String generateConstants(List constants, String pkgName) { + String result = ""; + if (constants != null) { + for (Constant c : constants) { + result = result + GeneratorUtil.createConstant(c, TAB, imports, pkgName) + NL; + } + result.concat(NL); + } + return result; + } - public String generateMethods(List methods, String pkgName) { - String result = ""; + public String generateMethods(List methods, String pkgName) { + String result = ""; - if (methods != null) { - for (MethodSignature m : methods) { - result = result - + GeneratorUtil.createMethodDeclaration(m, TAB, - imports, pkgName) + NL; - } - result = result + NL; - } - return result; - } + if (methods != null) { + for (MethodSignature m : methods) { + result = result + GeneratorUtil.createMethodDeclaration(m, TAB, imports, pkgName) + NL; + } + result = result + NL; + } + return result; + } - public Writer generate(Type type) throws IOException { - Writer writer = new StringWriter(); - if (type instanceof GeneratedType - && !(type instanceof GeneratedTransferObject)) { - GeneratedType genType = (GeneratedType) type; - imports = GeneratorUtil.createImports(genType); + public Writer generate(Type type) throws IOException { + Writer writer = new StringWriter(); + if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) { + final GeneratedType genType = (GeneratedType) type; + imports = GeneratorUtil.createImports(genType); - final String currentPkg = genType.getPackageName(); - final List constants = genType.getConstantDefinitions(); - final List methods = genType - .getMethodDefinitions(); - final List enums = genType.getEnumerations(); + final String currentPkg = genType.getPackageName(); + final List constants = genType.getConstantDefinitions(); + final List methods = genType.getMethodDefinitions(); + final List enums = genType.getEnumerations(); - writer.write(GeneratorUtil.createPackageDeclaration(genType - .getPackageName())); - writer.write(NL); + writer.write(GeneratorUtil.createPackageDeclaration(genType.getPackageName())); + writer.write(NL); - List importLines = GeneratorUtil.createImportLines(imports); - for (String line : importLines) { - writer.write(line + NL); - } - writer.write(NL); - writer.write(GeneratorUtil.createIfcDeclaration(genType, "", - imports)); - writer.write(NL); + final List importLines = GeneratorUtil.createImportLines(imports); + for (String line : importLines) { + writer.write(line + NL); + } + writer.write(NL); + writer.write(GeneratorUtil.createIfcDeclaration(genType, "", imports)); + writer.write(NL); - writer.write(generateEnums(enums)); - writer.write(generateConstants(constants, currentPkg)); - writer.write(generateMethods(methods, currentPkg)); + writer.write(generateEnums(enums)); + writer.write(generateConstants(constants, currentPkg)); + writer.write(generateMethods(methods, currentPkg)); - writer.write(RCB); - } - return writer; - } + writer.write(RCB); + } + return writer; + } } diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network-ne.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network-ne.yang index 41102aed44..8b576c3ce9 100644 --- a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network-ne.yang +++ b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network-ne.yang @@ -1,54 +1,54 @@ module controller-openflow-ne { - yang-version 1; - namespace "urn:opendaylight:controller:network:openflow"; - prefix "of"; - - import controller-network { - prefix cn; - } - import ietf-inet-types { prefix "inet"; } - - revision 2013-06-07 { - description "Initial demo"; - } + yang-version 1; + namespace "urn:opendaylight:controller:network:openflow"; + prefix "of"; + + import controller-network { + prefix cn; + } + import ietf-inet-types { prefix "inet"; } + + revision 2013-06-07 { + description "Initial demo"; + } - augment "/cn:network/cn:network-elements/cn:network-element" { + augment "/cn:network/cn:network-elements/cn:network-element" { - container flow-tables { - list flow-table { + container flow-tables { + list flow-table { - key "id"; - leaf id { - type int32; - } + key "id"; + leaf id { + type int32; + } - container flows { - list flow { - key "name"; - leaf name { - type string; - } - container match { - leaf input-port { - type cn:tp-ref; - } - leaf nl-src { - type inet:ipv4-address; - } - leaf nl-dst { - type inet:ipv4-address; - } - } - container actions { - list action { - leaf type { - type string; - } - } - } - } - } - } - } - } + container flows { + list flow { + key "name"; + leaf name { + type string; + } + container match { + leaf input-port { + type cn:tp-ref; + } + leaf nl-src { + type inet:ipv4-address; + } + leaf nl-dst { + type inet:ipv4-address; + } + } + container actions { + list action { + leaf type { + type string; + } + } + } + } + } + } + } + } } \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network.yang index 600e87d267..ce0b6b0824 100644 --- a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network.yang +++ b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network.yang @@ -1,171 +1,167 @@ module controller-network { - yang-version 1; - namespace "urn:opendaylight:controller:network"; - prefix "topos"; - - import ietf-inet-types { prefix "inet"; } - - revision 2013-05-20 { - description "Initial demo"; - } - + yang-version 1; + namespace "urn:opendaylight:controller:network"; + prefix "topos"; + + import ietf-inet-types { prefix "inet"; } + + revision 2013-05-20 { + description "Initial demo"; + } - - typedef topology-id { - type string; - } + typedef topology-id { + type string; + } - typedef node-id { - type string; - } + typedef node-id { + type string; + } - typedef link-id { - type string; - } + typedef link-id { + type string; + } - typedef tp-id { - type string; - description "identifier for termination points on a port"; - } + typedef tp-id { + type string; + description "identifier for termination points on a port"; + } - typedef tp-ref { - type leafref { - path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id"; - } - } - typedef topology-ref { - type leafref { - path "/network/topologies/topology/topology-id"; - } - description "This type is used for leafs that reference topology identifier instance."; - // currently not used - } + typedef tp-ref { + type leafref { + path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id"; + } + } + typedef topology-ref { + type leafref { + path "/network/topologies/topology/topology-id"; + } + description "This type is used for leafs that reference topology identifier instance."; + // currently not used + } - typedef node-ref { - type leafref { - path "/network/topologies/topology/nodes/node/node-id"; - } - description "This type is used for leafs that reference a node instance."; - } + typedef node-ref { + type leafref { + path "/network/topologies/topology/nodes/node/node-id"; + } + description "This type is used for leafs that reference a node instance."; + } - typedef link-ref { - type leafref { - path "/network/topologies/topology/links/link/link-id"; - } - description "This type is used for leafs that reference a link instance."; - // currently not used - } - - typedef network-element-ref { - type leafref { - path "/network/network-elements/network-element/element-id"; - } - } + typedef link-ref { + type leafref { + path "/network/topologies/topology/links/link/link-id"; + } + description "This type is used for leafs that reference a link instance."; + // currently not used + } + + typedef network-element-ref { + type leafref { + path "/network/network-elements/network-element/element-id"; + } + } + typedef element-id { + type string; + } + + container network { + container topologies { + list topology { + description " + This is the model of abstract topology which contains only Network + Nodes and Network Links. Each topology MUST be identified by + unique topology-id for reason that the store could contain many + topologies. + "; + key "topology-id"; + leaf topology-id { + type topology-id; + description " + It is presumed that datastore will contain many topologies. To + distinguish between topologies it is vital to have UNIQUE + topology identifier. + "; + } - typedef element-id { - type string; - } - - container network { - container topologies { - list topology { - description " - This is the model of abstract topology which contains only Network - Nodes and Network Links. Each topology MUST be identified by - unique topology-id for reason that the store could contain many - topologies. - "; - key "topology-id"; - leaf topology-id { - type topology-id; - description " - It is presumed that datastore will contain many topologies. To - distinguish between topologies it is vital to have UNIQUE - topology identifier. - "; - } + container types { + description " + The container for definition of topology types. + The augmenting modules should add empty optional leaf + to this container to signalize topology type."; + } - container types { - description " - The container for definition of topology types. - The augmenting modules should add empty optional leaf - to this container to signalize topology type. - "; - } + container nodes { + list node { + description "The list of network nodes defined for topology."; - container nodes { - list node { - description "The list of network nodes defined for topology."; + key "node-id"; + leaf node-id { + type node-id; + description "The Topology identifier of network-node."; + } - key "node-id"; - leaf node-id { - type node-id; - description "The Topology identifier of network-node."; - } - - leaf supporting-ne { - type network-element-ref; - } - - container termination-points { - list termination-point { - key "tp-id"; - leaf tp-id { - type tp-id; - } - } - } - } - } - - container links { - list link { - description " - The Network Link which is defined by Local (Source) and - Remote (Destination) Network Nodes. Every link MUST be - defined either by identifier and his local and remote - Network Nodes (in real applications it is common that many - links are originated from one node and end up in same - remote node). To ensure that we would always know to - distinguish between links, every link SHOULD have - identifier. - "; - key "link-id"; - - leaf link-id { - type link-id; - } - container source { - leaf source-node { - type node-ref; - description "Source node identifier."; - } - leaf source-tp { - type tp-ref; - } - } - container destination { - leaf dest-node { - type node-ref; - description "Destination node identifier."; - } - leaf dest-tp { - type tp-ref; - } - } - } - } - } - } - container network-elements { - config true; - list network-element { - key "element-id"; - leaf element-id { - type element-id; - } - } - } - } + leaf supporting-ne { + type network-element-ref; + } + + container termination-points { + list termination-point { + key "tp-id"; + leaf tp-id { + type tp-id; + } + } + } + } + } + + container links { + list link { + description " + The Network Link which is defined by Local (Source) and + Remote (Destination) Network Nodes. Every link MUST be + defined either by identifier and his local and remote + Network Nodes (in real applications it is common that many + links are originated from one node and end up in same + remote node). To ensure that we would always know to + distinguish between links, every link SHOULD have + identifier. + "; + key "link-id"; + + leaf link-id { + type link-id; + } + container source { + leaf source-node { + type node-ref; + description "Source node identifier."; + } + leaf source-tp { + type tp-ref; + } + } + container destination { + leaf dest-node { + type node-ref; + description "Destination node identifier."; + } + leaf dest-tp { + type tp-ref; + } + } + } + } + } + } + container network-elements { + config true; + list network-element { + key "element-id"; + leaf element-id { + type element-id; + } + } + } + } } diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow-ipv6.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow-ipv6.yang index 1d357bde0a..eec19092fd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow-ipv6.yang +++ b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow-ipv6.yang @@ -12,20 +12,6 @@ module controller-openflow-ipv6 { revision 2013-06-07 { description "Initial demo"; } - - - - augment "/cn:network/cn:network-elements/cn:network-element/of:flow-tables/of:flow-table/of:flows/of:flow/of:match" { - - leaf nl-src { - type inet:ipv6-prefix; - } - - leaf nl-dst { - type inet:ipv6-prefix; - } - } - } \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow.yang index 62e937e92b..83f69c4dc2 100644 --- a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow.yang +++ b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow.yang @@ -3,16 +3,11 @@ module controller-openflow { namespace "urn:opendaylight:controller:openflow"; prefix "of"; import controller-network {prefix cn;} - - + revision 2013-05-20 { description "Initial demo"; } - - - - typedef datapath-id { type string { length 16; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java index 554866712f..2a7bca4aa5 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java @@ -1009,13 +1009,24 @@ public final class ParserUtils { for (int i = 1; i < path.size(); i++) { final QName currentQName = path.get(i); DataSchemaNodeBuilder newParent = null; - for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodeBuilders()) { - final QName childQName = child.getQName(); - if (childQName.getLocalName().equals(currentQName.getLocalName())) { - newParent = child; - break; + if(currentParent instanceof DataNodeContainerBuilder) { + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodeBuilders()) { + final QName childQName = child.getQName(); + if (childQName.getLocalName().equals(currentQName.getLocalName())) { + newParent = child; + break; + } + } + } else if(currentParent instanceof ChoiceBuilder) { + for(ChoiceCaseBuilder caseBuilder : ((ChoiceBuilder)currentParent).getCases()) { + final QName caseQName = caseBuilder.getQName(); + if (caseQName.getLocalName().equals(currentQName.getLocalName())) { + newParent = caseBuilder; + break; + } } } + if (newParent == null) { break; // node not found, quit search } else { diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/InstanceIdentifier.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/InstanceIdentifier.java new file mode 100644 index 0000000000..7d13655099 --- /dev/null +++ b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/InstanceIdentifier.java @@ -0,0 +1,12 @@ +package org.opendaylight.controller.yang.binding; + +/** + * Created with IntelliJ IDEA. + * User: lsedlak + * Date: 27.6.2013 + * Time: 11:44 + * To change this template use File | Settings | File Templates. + */ +public class InstanceIdentifier { + +}