Bug 1411 #3 BindingGeneratorImpl decomposition - Leafs 68/53268/4
authorMartin Ciglan <mciglan@cisco.com>
Tue, 14 Mar 2017 10:29:50 +0000 (11:29 +0100)
committerMartin Ciglan <mciglan@cisco.com>
Mon, 20 Mar 2017 09:02:30 +0000 (10:02 +0100)
- resolve Leafs from schema context
- preprare getters
- further util methods added
- further decomposition in order to
decrease initial BindingGeneratorImpl complexity

Change-Id: If352546fb4f0fb375705959a54242e657c285e75
Signed-off-by: Martin Ciglan <mciglan@cisco.com>
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AugmentToGenType.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AuxiliaryGenUtils.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/BindingGeneratorImpl.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/ModuleToGenType.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/yang/types/TypeProviderImpl.java

index f7735f6d63c40efb5329be85410f03b401c205ea..685197f9a3f218737dd95ff6951a38f047c1a8f8 100644 (file)
@@ -18,6 +18,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
 import org.opendaylight.mdsal.binding.javav2.generator.util.ReferencedTypeImpl;
 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
@@ -87,8 +88,8 @@ final class AugmentToGenType {
      *             if set of augmentations from module is null
      */
     static Map<Module, ModuleContext> generate(final Module module, final SchemaContext schemaContext,
-            final Map<Module, ModuleContext> genCtx, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
-            final boolean verboseClassComments) {
+            final TypeProvider typeProvider, final Map<Module, ModuleContext> genCtx,
+            Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final boolean verboseClassComments) {
 
         Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
         Preconditions.checkArgument(module.getName() != null, "Module name cannot be NULL.");
@@ -99,7 +100,7 @@ final class AugmentToGenType {
         Map<Module, ModuleContext> resultCtx = genCtx;
         for (final AugmentationSchema augment : augmentations) {
             resultCtx = augmentationToGenTypes(basePackageName, augment, module, schemaContext, verboseClassComments,
-                    resultCtx, genTypeBuilders);
+                    resultCtx, genTypeBuilders, typeProvider);
         }
         return resultCtx;
     }
@@ -158,7 +159,8 @@ final class AugmentToGenType {
      */
     private static Map<Module, ModuleContext> augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema,
             final Module module, final SchemaContext schemaContext, final boolean verboseClassComments,
-            Map<Module, ModuleContext> genCtx, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+            Map<Module, ModuleContext> genCtx, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+            final TypeProvider typeProvider) {
 
         Map<Module, ModuleContext> generatedCtx;
         Preconditions.checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
@@ -167,7 +169,7 @@ final class AugmentToGenType {
                 "Augmentation Schema does not contain Target Path (Target Path is NULL).");
 
         generatedCtx = GenHelperUtil.processUsesAugments(schemaContext, augSchema, module, genCtx, genTypeBuilders,
-                verboseClassComments);
+                verboseClassComments, typeProvider);
         final SchemaPath targetPath = augSchema.getTargetPath();
         SchemaNode targetSchemaNode;
 
@@ -205,7 +207,7 @@ final class AugmentToGenType {
         } else {
             generatedCtx = generateTypesFromAugmentedChoiceCases(schemaContext, module, augmentPackageName,
                     targetTypeBuilder.toInstance(), (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes(),
-                    null, generatedCtx, verboseClassComments, genTypeBuilders);
+                    null, generatedCtx, verboseClassComments, genTypeBuilders, typeProvider);
             return generatedCtx;
         }
     }
@@ -214,7 +216,7 @@ final class AugmentToGenType {
                         augmentPackageName, final AugmentationSchema augSchema, final Module module, final UsesNode usesNode, final DataNodeContainer
                         usesNodeParent, Map<Module, ModuleContext> genCtx,
                         Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
-                        final boolean verboseClassComments) {
+                        final boolean verboseClassComments, final TypeProvider typeProvider) {
 
         Map<Module, ModuleContext> generatedCtx;
         Preconditions.checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
@@ -223,7 +225,7 @@ final class AugmentToGenType {
                 "Augmentation Schema does not contain Target Path (Target Path is NULL).");
 
         generatedCtx = GenHelperUtil.processUsesAugments(schemaContext, augSchema, module, genCtx, genTypeBuilders,
-                verboseClassComments);
+                verboseClassComments, typeProvider);
         final SchemaPath targetPath = augSchema.getTargetPath();
         final SchemaNode targetSchemaNode = findOriginalTargetFromGrouping(schemaContext, targetPath, usesNode);
         if (targetSchemaNode == null) {
@@ -251,7 +253,7 @@ final class AugmentToGenType {
         } else {
             generatedCtx = generateTypesFromAugmentedChoiceCases(schemaContext, module, augmentPackageName,
                     targetTypeBuilder.toInstance(), (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes(),
-                    usesNodeParent, generatedCtx, verboseClassComments, genTypeBuilders);
+                    usesNodeParent, generatedCtx, verboseClassComments, genTypeBuilders, typeProvider);
             return generatedCtx;
         }
     }
@@ -348,7 +350,7 @@ final class AugmentToGenType {
                           final String basePackageName, final Type targetType, final ChoiceSchemaNode targetNode,
                           final Iterable<DataSchemaNode> augmentedNodes, final DataNodeContainer usesNodeParent,
                           Map<Module, ModuleContext> genCtx, final boolean verboseClassComments,
-                          Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+                          Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
         Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
         Preconditions.checkArgument(targetType != null, "Referenced Choice Type cannot be NULL.");
         Preconditions.checkArgument(augmentedNodes != null, "Set of Choice Case Nodes cannot be NULL.");
@@ -399,7 +401,7 @@ final class AugmentToGenType {
                 final Iterable<DataSchemaNode> childNodes = node.getChildNodes();
                 if (childNodes != null) {
                     GenHelperUtil.resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType,
-                            childNodes, genCtx, schemaContext, verboseClassComments, genTypeBuilders);
+                            childNodes, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
                 }
                 genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder);
                 genCtx.get(module).addChoiceToCaseMapping(targetType, caseTypeBuilder, node);
index 94a225adeecd4fb20a1ff958d53b800868998d46..c5977ae4801b84fb03307f2bb369a274f5c31303 100644 (file)
@@ -16,23 +16,35 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 import org.opendaylight.mdsal.binding.javav2.generator.impl.txt.yangTemplateForModule;
 import org.opendaylight.mdsal.binding.javav2.generator.impl.txt.yangTemplateForNode;
 import org.opendaylight.mdsal.binding.javav2.generator.impl.util.YangTextTemplate;
+import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
 import org.opendaylight.mdsal.binding.javav2.generator.util.NonJavaCharsConverter;
 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
+import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
+import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
+import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
 import org.opendaylight.mdsal.binding.javav2.model.api.Constant;
 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
+import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
+import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
+import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilderBase;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
@@ -40,7 +52,11 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 
 /**
@@ -268,6 +284,165 @@ final class AuxiliaryGenUtils {
         return null;
     }
 
+    /**
+     * Adds enumeration builder created from <code>enumTypeDef</code> to
+     * <code>typeBuilder</code>.
+     *
+     * Each <code>enumTypeDef</code> item is added to builder with its name and
+     * value.
+     *
+     * @param enumTypeDef
+     *            EnumTypeDefinition contains enum data
+     * @param enumName
+     *            string contains name which will be assigned to enumeration
+     *            builder
+     * @param typeBuilder
+     *            GeneratedTypeBuilder to which will be enum builder assigned
+     * @param module
+     *            Module in which type should be generated
+     * @return enumeration builder which contains data from
+     *         <code>enumTypeDef</code>
+     */
+    static EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final QName enumName,
+        final Map<Module, ModuleContext> genCtx, final GeneratedTypeBuilder typeBuilder, final Module module) {
+        if (enumTypeDef != null && typeBuilder != null && enumTypeDef.getQName().getLocalName() != null) {
+            final String enumerationName = BindingMapping.getClassName(enumName);
+            final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
+            final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
+            enumBuilder.setDescription(enumTypedefDescription);
+            enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
+            ModuleContext ctx = genCtx.get(module);
+            ctx.addInnerTypedefType(enumTypeDef.getPath(), enumBuilder);
+            return enumBuilder;
+        }
+        return null;
+    }
+
+
+    /**
+     * Builds generated TO builders for <code>typeDef</code> of type
+     * {@link UnionTypeDefinition} or {@link BitsTypeDefinition} which are
+     * also added to <code>typeBuilder</code> as enclosing transfer object.
+     *
+     * If more then one generated TO builder is created for enclosing then all
+     * of the generated TO builders are added to <code>typeBuilder</code> as
+     * enclosing transfer objects.
+     *
+     * @param typeDef
+     *            type definition which can be of type <code>UnionType</code> or
+     *            <code>BitsTypeDefinition</code>
+     * @param typeBuilder
+     *            generated type builder to which is added generated TO created
+     *            from <code>typeDef</code>
+     * @param leaf
+     *            string with name for generated TO builder
+     * @param parentModule
+     *            parent module
+     * @return generated TO builder for <code>typeDef</code>
+     */
+    static GeneratedTOBuilder addTOToTypeBuilder(final TypeDefinition<?> typeDef, final GeneratedTypeBuilder
+            typeBuilder, final DataSchemaNode leaf, final Module parentModule, final TypeProvider typeProvider,
+            final SchemaContext schemaContext) {
+        final String classNameFromLeaf = BindingMapping.getClassName(leaf.getQName());
+        final List<GeneratedTOBuilder> genTOBuilders = new ArrayList<>();
+        final String packageName = typeBuilder.getFullyQualifiedName();
+        if (typeDef instanceof UnionTypeDefinition) {
+            final List<GeneratedTOBuilder> types = ((TypeProviderImpl) typeProvider)
+                    .provideGeneratedTOBuildersForUnionTypeDef(packageName, ((UnionTypeDefinition) typeDef),
+                            classNameFromLeaf, leaf, schemaContext, ((TypeProviderImpl) typeProvider).getGenTypeDefsContextMap());
+            genTOBuilders.addAll(types);
+
+            GeneratedTOBuilder resultTOBuilder;
+            if (types.isEmpty()) {
+                throw new IllegalStateException("No GeneratedTOBuilder objects generated from union " + typeDef);
+            }
+            resultTOBuilder = types.remove(0);
+            for (final GeneratedTOBuilder genTOBuilder : types) {
+                resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
+            }
+
+            final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
+            genPropBuilder.setReturnType(Types.CHAR_ARRAY);
+            resultTOBuilder.addEqualsIdentity(genPropBuilder);
+            resultTOBuilder.addHashIdentity(genPropBuilder);
+            resultTOBuilder.addToStringProperty(genPropBuilder);
+
+        } else if (typeDef instanceof BitsTypeDefinition) {
+            genTOBuilders.add((((TypeProviderImpl) typeProvider)).provideGeneratedTOBuilderForBitsTypeDefinition(
+                    packageName, typeDef, classNameFromLeaf, parentModule.getName()));
+        }
+        if (!genTOBuilders.isEmpty()) {
+            for (final GeneratedTOBuilder genTOBuilder : genTOBuilders) {
+                typeBuilder.addEnclosingTransferObject(genTOBuilder);
+            }
+            return genTOBuilders.get(0);
+        }
+        return null;
+
+    }
+
+    static Type createReturnTypeForUnion(final GeneratedTOBuilder genTOBuilder, final TypeDefinition<?> typeDef,
+            final GeneratedTypeBuilder typeBuilder, final Module parentModule, final TypeProvider typeProvider) {
+        final GeneratedTOBuilderImpl returnType = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(),
+                genTOBuilder.getName());
+        final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
+
+        returnType.setDescription(typedefDescription);
+        returnType.setReference(typeDef.getReference());
+        returnType.setSchemaPath((List) typeDef.getPath().getPathFromRoot());
+        returnType.setModuleName(parentModule.getName());
+
+        genTOBuilder.setTypedef(true);
+        genTOBuilder.setIsUnion(true);
+        TypeProviderImpl.addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
+
+
+
+        final GeneratedTOBuilder unionBuilder = createUnionBuilder(genTOBuilder,typeBuilder);
+
+
+        final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
+        method.setReturnType(returnType);
+        method.addParameter(Types.STRING, "defaultValue");
+        method.setAccessModifier(AccessModifier.PUBLIC);
+        method.setStatic(true);
+
+        final Set<Type> types = ((TypeProviderImpl) typeProvider).getAdditionalTypes().get(parentModule);
+        if (types == null) {
+            ((TypeProviderImpl) typeProvider).getAdditionalTypes().put(parentModule,
+                    Sets.newHashSet(unionBuilder.toInstance()));
+        } else {
+            types.add(unionBuilder.toInstance());
+        }
+        return returnType.toInstance();
+    }
+
+    private static GeneratedTOBuilder createUnionBuilder(final GeneratedTOBuilder genTOBuilder, final GeneratedTypeBuilder typeBuilder) {
+        final String outerCls = Types.getOuterClassName(genTOBuilder);
+        final StringBuilder name;
+        if (outerCls != null) {
+            name = new StringBuilder(outerCls);
+        } else {
+            name = new StringBuilder();
+        }
+        name.append(genTOBuilder.getName());
+        name.append("Builder");
+        final GeneratedTOBuilderImpl unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(),name.toString());
+        unionBuilder.setIsUnionBuilder(true);
+        return unionBuilder;
+    }
+
+    static boolean isInnerType(final LeafSchemaNode leaf, final TypeDefinition<?> type) {
+        if (leaf.getPath().equals(type.getPath())) {
+            return true;
+        }
+        if (leaf.getPath().equals(type.getPath().getParent())) {
+            return true;
+        }
+
+        return false;
+    }
+
     @VisibleForTesting
     public static String replaceAllIllegalChars(final StringBuilder stringBuilder){
         final String ret = UNICODE_CHAR_PATTERN.matcher(stringBuilder).replaceAll("\\\\\\\\u");
index c149193ec328f8bc70c3ada4f77f4adce068af5c..fd9e8460f744e225ab3c4ddfaed4889dc6ac6bbc 100644 (file)
@@ -128,7 +128,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     genCtx, verboseClassComments);
         }
         for (final Module contextModule : contextModules) {
-            genCtx = AugmentToGenType.generate(contextModule, context, genCtx,
+            genCtx = AugmentToGenType.generate(contextModule, context, typeProvider, genCtx,
                     genTypeBuilders, verboseClassComments);
         }
 
index f55f411f8a948d14f5d16834a65ba355ed58e27b..4b618fbb87bf28a3defbe5bf01d6489ff9ba085a 100644 (file)
@@ -8,26 +8,39 @@
 
 package org.opendaylight.mdsal.binding.javav2.generator.impl;
 
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.addTOToTypeBuilder;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.annotateDeprecatedIfNecessary;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.augGenTypeName;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.constructGetter;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createReturnTypeForUnion;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.getAugmentIdentifier;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.isInnerType;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.qNameConstant;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveInnerEnumFromTypeDefinition;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
+
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
+import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes;
 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
 import org.opendaylight.mdsal.binding.javav2.generator.util.NonJavaCharsConverter;
 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
+import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType;
+import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
+import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
+import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
+import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
 import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentable;
@@ -38,11 +51,16 @@ import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 
 /**
@@ -179,13 +197,14 @@ final class GenHelperUtil {
                           final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf,
                           final Iterable<DataSchemaNode> schemaNodes, final Map<Module, ModuleContext> genCtx,
                           final SchemaContext schemaContext, final boolean verboseClassComments,
-                          final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+                          final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+                          final TypeProvider typeProvider) {
 
         if (schemaNodes != null && parent != null) {
             for (final DataSchemaNode schemaNode : schemaNodes) {
                 if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) {
                     addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module, genCtx,
-                            schemaContext, verboseClassComments, genTypeBuilders);
+                            schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
                 }
             }
         }
@@ -200,15 +219,16 @@ final class GenHelperUtil {
     }
 
     static Map<Module, ModuleContext> processUsesAugments(final SchemaContext schemaContext, final
-                        DataNodeContainer node, final Module module, Map<Module, ModuleContext> genCtx,  final Map<String,
-                        Map<String, GeneratedTypeBuilder>> genTypeBuilders, final boolean verboseClassComments) {
+                        DataNodeContainer node, final Module module, Map<Module, ModuleContext> genCtx,
+                        final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+                        final boolean verboseClassComments, final TypeProvider typeProvider) {
         final String basePackageName = BindingMapping.getRootPackageName(module);
         for (final UsesNode usesNode : node.getUses()) {
             for (final AugmentationSchema augment : usesNode.getAugmentations()) {
                 genCtx = AugmentToGenType.usesAugmentationToGenTypes(schemaContext, basePackageName, augment, module,
-                        usesNode,
-                        node, genCtx, genTypeBuilders, verboseClassComments);
-                genCtx = processUsesAugments(schemaContext, augment, module, genCtx, genTypeBuilders, verboseClassComments);
+                        usesNode, node, genCtx, genTypeBuilders, verboseClassComments, typeProvider);
+                genCtx = processUsesAugments(schemaContext, augment, module, genCtx, genTypeBuilders,
+                        verboseClassComments, typeProvider);
             }
         }
         return genCtx;
@@ -446,12 +466,15 @@ final class GenHelperUtil {
     private static void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode node,
         final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Module module,
         final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext, final boolean verboseClassComments,
-        final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+        final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
         //TODO: implement rest of schema nodes GTO building
         if (node != null && typeBuilder != null) {
             if (node instanceof ContainerSchemaNode) {
                 containerToGenType(module, basePackageName, typeBuilder, childOf, (ContainerSchemaNode) node,
-                        schemaContext, verboseClassComments, genCtx, genTypeBuilders);
+                        schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider);
+            } else if (node instanceof LeafSchemaNode) {
+                resolveLeafSchemaNodeAsMethod(schemaContext, typeBuilder, genCtx, (LeafSchemaNode) node, module,
+                        typeProvider);
             }
         }
 
@@ -460,21 +483,117 @@ final class GenHelperUtil {
     private static void containerToGenType(final Module module, final String basePackageName,
         final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ContainerSchemaNode node,
         final SchemaContext schemaContext, final boolean verboseClassComments, final Map<Module, ModuleContext> genCtx,
-        final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+        final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
 
         final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node,
-                schemaContext, verboseClassComments, genCtx, genTypeBuilders);
+                schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider);
         if (genType != null) {
             constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType, node.getStatus());
             resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes(), genCtx,
-                    schemaContext, verboseClassComments, genTypeBuilders);
+                    schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
+        }
+    }
+
+    /**
+     * Converts <code>leaf</code> to the getter method which is added to
+     * <code>typeBuilder</code>.
+     *
+     * @param typeBuilder
+     *            generated type builder to which is added getter method as
+     *            <code>leaf</code> mapping
+     * @param leaf
+     *            leaf schema node which is mapped as getter method which is
+     *            added to <code>typeBuilder</code>
+     * @param module
+     *            Module in which type was defined
+     * @return boolean value
+     *         <ul>
+     *         <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
+     *         null</li>
+     *         <li>true - in other cases</li>
+     *         </ul>
+     */
+    private static Type resolveLeafSchemaNodeAsMethod(final SchemaContext schemaContext, final GeneratedTypeBuilder
+            typeBuilder, final Map<Module, ModuleContext> genCtx, final LeafSchemaNode leaf, final Module module,
+            final TypeProvider typeProvider) {
+        if (leaf == null || typeBuilder == null || leaf.isAddedByUses()) {
+            return null;
+        }
+
+        final String leafName = leaf.getQName().getLocalName();
+        if (leafName == null) {
+            return null;
         }
+
+        final Module parentModule = findParentModule(schemaContext, leaf);
+        Type returnType = null;
+
+        final TypeDefinition<?> typeDef = leaf.getType();
+        if (isInnerType(leaf, typeDef)) {
+            if (typeDef instanceof EnumTypeDefinition) {
+                returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
+                final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
+                final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(),
+                        genCtx, typeBuilder, module);
+                if (enumBuilder != null) {
+                    returnType = enumBuilder.toInstance(typeBuilder);
+                }
+                ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
+            } else if (typeDef instanceof UnionTypeDefinition) {
+                GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
+                        typeProvider, schemaContext);
+                if (genTOBuilder != null) {
+                    //TODO: https://bugs.opendaylight.org/show_bug.cgi?id=2289
+                    returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
+                }
+            } else if (typeDef instanceof BitsTypeDefinition) {
+                GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
+                        typeProvider, schemaContext);
+                if (genTOBuilder != null) {
+                    returnType = genTOBuilder.toInstance();
+                }
+            } else {
+                // It is constrained version of already declared type (inner declared type exists,
+                // onlyfor special cases (Enum, Union, Bits), which were already checked.
+                // In order to get proper class we need to look up closest derived type
+                // and apply restrictions from leaf type
+                final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+                returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf,
+                        restrictions);
+            }
+        } else {
+            final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+            returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions);
+        }
+
+        if (returnType == null) {
+            return null;
+        }
+
+        if (typeDef instanceof EnumTypeDefinition) {
+            ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
+        }
+
+        String leafDesc = leaf.getDescription();
+        if (leafDesc == null) {
+            leafDesc = "";
+        }
+
+        final MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType, leaf.getStatus());
+
+        //FIXME: deal with context-ref
+        return returnType;
+    }
+
+    private static TypeDefinition<?> getBaseOrDeclaredType(final TypeDefinition<?> typeDef) {
+        final TypeDefinition<?> baseType = typeDef.getBaseType();
+        return (baseType != null && baseType.getBaseType() != null) ? baseType : typeDef;
     }
 
     private static GeneratedTypeBuilder processDataSchemaNode(final Module module, final String basePackageName,
         final GeneratedTypeBuilder childOf, final DataSchemaNode node, final SchemaContext schemaContext,
         final boolean verboseClassComments, final Map<Module, ModuleContext> genCtx, final Map<String, Map<String,
-        GeneratedTypeBuilder>> genTypeBuilders) {
+        GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
 
         if (node.isAugmenting() || node.isAddedByUses()) {
             return null;
@@ -493,7 +612,7 @@ final class GenHelperUtil {
             //TODO: implement groupings to GTO building first
             // groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings());
             processUsesAugments(schemaContext, (DataNodeContainer) node, module, genCtx, genTypeBuilders,
-                    verboseClassComments);
+                    verboseClassComments, typeProvider);
         }
         return genType;
     }
index 864ee25a24833432055442b45795ee122ac06c39..f98f64a82b6565f5f8b530d4041bd1002fecc18a 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.mdsal.binding.javav2.generator.impl;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
@@ -44,7 +43,7 @@ final class ModuleToGenType {
             genCtx.get(module).addModuleNode(moduleType);
             final String basePackageName = BindingMapping.getRootPackageName(module);
             GenHelperUtil.resolveDataSchemaNodes(module, basePackageName, moduleType, moduleType, module
-                    .getChildNodes(), genCtx, schemaContext, verboseClassComments, genTypeBuilders);
+                    .getChildNodes(), genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
         }
 
         return genCtx;
index 7a35e0ddc97dbca2edc2e0cc6b0762eae35a4132..1c74adafc595bf1e8086b558696daed4314c3611 100644 (file)
@@ -162,6 +162,10 @@ public final class TypeProviderImpl implements TypeProvider {
         return null;
     }
 
+    public Map<String, Map<Date, Map<String, Type>>> getGenTypeDefsContextMap() {
+        return genTypeDefsContextMap;
+    }
+
     /**
      * Passes through all modules and through all its type definitions and
      * convert it to generated types.
@@ -287,7 +291,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if <code>basePackageName</code> equals null</li>
      *             </ul>
      */
-    public static GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, final
+    public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, final
     TypeDefinition<?> typeDef, final String typeDefName, final String moduleName) {
 
         Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");