X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=code-generator%2Fbinding-generator-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fsal%2Fbinding%2Fgenerator%2Fimpl%2FBindingGeneratorImpl.java;h=d448db765947b544e5d2ef3d3da289ab52da4af0;hb=5feac31a11a337a0c840f73c5c4612a6c997fa2a;hp=ce3f7397b4cfad0a136b469093f763b8b3ac6af9;hpb=eee777b33567d285c56fa0a2f7152bf0bfe6c253;p=yangtools.git diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java index ce3f7397b4..d448db7659 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java @@ -7,40 +7,69 @@ */ package org.opendaylight.yangtools.sal.binding.generator.impl; -import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.computeDefaultSUID; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType; +import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.DATA_OBJECT; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.DATA_ROOT; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.IDENTIFIABLE; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.IDENTIFIER; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.NOTIFICATION; +import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.augmentable; +import static org.opendaylight.yangtools.binding.generator.util.Types.BOOLEAN; +import static org.opendaylight.yangtools.binding.generator.util.Types.FUTURE; +import static org.opendaylight.yangtools.binding.generator.util.Types.VOID; +import static org.opendaylight.yangtools.binding.generator.util.Types.typeForClass; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findNodeInSchemaContext; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; + +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Future; +import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil; +import org.opendaylight.yangtools.binding.generator.util.BindingTypes; import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; import org.opendaylight.yangtools.binding.generator.util.Types; +import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl; import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator; import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider; +import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier; +import org.opendaylight.yangtools.sal.binding.model.api.Constant; import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject; import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType; import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; +import org.opendaylight.yangtools.sal.binding.model.api.Restrictions; import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder; import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort; import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl; -import org.opendaylight.yangtools.yang.binding.Augmentable; -import org.opendaylight.yangtools.yang.binding.DataRoot; -import org.opendaylight.yangtools.yang.binding.Identifiable; -import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.BindingMapping; +import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; @@ -49,12 +78,14 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceNode; 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.DerivableSchemaNode; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; 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.ModuleImport; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -65,26 +96,25 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; 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.EnumTypeDefinition.EnumPair; import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; -import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.opendaylight.yangtools.yang.model.util.UnionType; -import static org.opendaylight.yangtools.binding.generator.util.Types.*; -import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; +import org.opendaylight.yangtools.yang.parser.builder.util.Comparators; +import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +public class BindingGeneratorImpl implements BindingGenerator { + private static final Logger LOG = LoggerFactory.getLogger(BindingGeneratorImpl.class); -import com.google.common.base.Preconditions; -import com.google.common.base.Predicates; - -public final class BindingGeneratorImpl implements BindingGenerator { + private final Map genCtx = new HashMap<>(); /** - * Outter key represents the package name. Outter value represents map of - * all builders in the same package. Inner key represents the schema node - * name (in JAVA class/interface name format). Inner value represents - * instance of builder for schema node specified in key part. + * Outer key represents the package name. Outer value represents map of all + * builders in the same package. Inner key represents the schema node name + * (in JAVA class/interface name format). Inner value represents instance of + * builder for schema node specified in key part. */ private Map> genTypeBuilders; @@ -94,21 +124,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { private TypeProvider typeProvider; /** - * Holds reference to schema context to resolve data of augmented elemnt + * Holds reference to schema context to resolve data of augmented element * when creating augmentation builder */ private SchemaContext schemaContext; - /** - * Each grouping which is converted from schema node to generated type is - * added to this map with its Schema path as key to make it easier to get - * reference to it. In schema nodes in uses attribute there is - * only Schema Path but when building list of implemented interfaces for - * Schema node the object of type Type is required. So in this - * case is used this map. - */ - private final Map allGroupings = new HashMap(); - /** * Constant with the concrete name of namespace. */ @@ -119,13 +139,6 @@ public final class BindingGeneratorImpl implements BindingGenerator { */ private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; - /** - * Only parent constructor is invoked. - */ - public BindingGeneratorImpl() { - super(); - } - /** * Resolves generated types from context schema nodes of all * modules. @@ -140,37 +153,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { * GeneratedTransferObjectwhich are generated from * context data. * @throws IllegalArgumentException - * if param context is null + * if arg context is null * @throws IllegalStateException * if context contain no modules */ @Override public List generateTypes(final SchemaContext context) { - Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); - Preconditions.checkState(context.getModules() != null,"Schema Context does not contain defined modules."); - final List generatedTypes = new ArrayList<>(); + checkArgument(context != null, "Schema Context reference cannot be NULL."); + checkState(context.getModules() != null, "Schema Context does not contain defined modules."); schemaContext = context; typeProvider = new TypeProviderImpl(context); final Set modules = context.getModules(); - genTypeBuilders = new HashMap<>(); - for (final Module module : modules) { - - generatedTypes.addAll(allGroupingsToGenTypes(module)); - - if (false == module.getChildNodes().isEmpty()) { - generatedTypes.add(moduleToDataType(module)); - } - 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)); - generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); - - } - return generatedTypes; + return generateTypes(context, modules); } /** @@ -195,191 +189,159 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * @throws IllegalArgumentException *
    - *
  • if param context is null or
  • - *
  • if param modules is null
  • + *
  • if arg context is null or
  • + *
  • if arg modules is null
  • *
* @throws IllegalStateException * if context contain no modules */ @Override public List generateTypes(final SchemaContext context, final Set modules) { - Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); - Preconditions.checkState(context.getModules() != null,"Schema Context does not contain defined modules."); - Preconditions.checkArgument(modules != null,"Sef of Modules cannot be NULL."); + checkArgument(context != null, "Schema Context reference cannot be NULL."); + checkState(context.getModules() != null, "Schema Context does not contain defined modules."); + checkArgument(modules != null, "Set of Modules cannot be NULL."); - final List filteredGenTypes = new ArrayList<>(); schemaContext = context; typeProvider = new TypeProviderImpl(context); - final Set contextModules = context.getModules(); + Module[] modulesArray = new Module[context.getModules().size()]; + context.getModules().toArray(modulesArray); + final List contextModules = ModuleDependencySort.sort(modulesArray); genTypeBuilders = new HashMap<>(); - for (final Module contextModule : contextModules) { - final List generatedTypes = new ArrayList<>(); - generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if (false == contextModule.getChildNodes().isEmpty()) { - generatedTypes.add(moduleToDataType(contextModule)); - } - 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)); - - if (modules.contains(contextModule)) { - filteredGenTypes.addAll(generatedTypes); + for (Module contextModule : contextModules) { + moduleToGenTypes(contextModule, context); + } + for (Module contextModule : contextModules) { + allAugmentsToGenTypes(contextModule); + } + + final List filteredGenTypes = new ArrayList<>(); + for (Module m : modules) { + final ModuleContext ctx = checkNotNull(genCtx.get(m), "Module context not found for module %s", m); + filteredGenTypes.addAll(ctx.getGeneratedTypes()); + final Set additionalTypes = ((TypeProviderImpl) typeProvider).getAdditionalTypes().get(m); + if (additionalTypes != null) { + filteredGenTypes.addAll(additionalTypes); } } + return filteredGenTypes; } + private void moduleToGenTypes(final Module m, final SchemaContext context) { + genCtx.put(m, new ModuleContext()); + allTypeDefinitionsToGenTypes(m); + groupingsToGenTypes(m, m.getGroupings()); + rpcMethodsToGenType(m); + allIdentitiesToGenTypes(m, context); + notificationsToGenType(m); + + if (!m.getChildNodes().isEmpty()) { + final GeneratedTypeBuilder moduleType = moduleToDataType(m); + genCtx.get(m).addModuleNode(moduleType); + final String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule()); + resolveDataSchemaNodes(m, basePackageName, moduleType, moduleType, m.getChildNodes()); + } + } + /** * Converts all extended type definitions of module to the list of * Type objects. * * @param module * module from which is obtained set of type definitions - * @return list of Type which are generated from extended - * definition types (object of type ExtendedType) * @throws IllegalArgumentException *
    - *
  • if module equals null
  • - *
  • if name of module equals null
  • - *
  • if type definitions of module equal null
  • + *
  • if module is null
  • + *
  • if name of module is null
  • *
- * + * @throws IllegalStateException + * if set of type definitions from module is null */ - private List allTypeDefinitionsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - Preconditions.checkArgument(module.getTypeDefinitions() != null,"Type Definitions for module " + module.getName() + " cannot be NULL."); - - final Set> typeDefinitions = module.getTypeDefinitions(); - final List generatedTypes = new ArrayList<>(); - for (final TypeDefinition typedef : typeDefinitions) { + private void allTypeDefinitionsToGenTypes(final Module module) { + checkArgument(module != null, "Module reference cannot be NULL."); + checkArgument(module.getName() != null, "Module name cannot be NULL."); + final DataNodeIterator it = new DataNodeIterator(module); + final List> typeDefinitions = it.allTypedefs(); + checkState(typeDefinitions != null, "Type Definitions for module «module.name» cannot be NULL."); + + for (TypeDefinition typedef : typeDefinitions) { if (typedef != null) { - final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef); - if ((type != null) && !generatedTypes.contains(type)) { - generatedTypes.add(type); + final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef, + typedef); + if (type != null) { + genCtx.get(module).addTypedefType(typedef.getPath(), type); } } } - return generatedTypes; } - /** - * Converts all containers of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all containers - * @return list of Type which are generated from containers - * (objects of type ContainerSchemaNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allContainersToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() - + " cannot be NULL."); + private GeneratedTypeBuilder processDataSchemaNode(final Module module, final String basePackageName, + final GeneratedTypeBuilder childOf, final DataSchemaNode node) { + if (node.isAugmenting() || node.isAddedByUses()) { + return null; } - - final List generatedTypes = new ArrayList<>(); - final DataNodeIterator it = new DataNodeIterator(module); - final List schemaContainers = it.allContainers(); - final String basePackageName = moduleNamespaceToPackageName(module); - for (final ContainerSchemaNode container : schemaContainers) { - if (!container.isAddedByUses()) { - generatedTypes.add(containerToGenType(basePackageName, container)); - } + final String packageName = packageNameForGeneratedType(basePackageName, node.getPath()); + final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, node, childOf); + genType.addComment(node.getDescription()); + if (node instanceof DataNodeContainer) { + genCtx.get(module).addChildNodeType(node.getPath(), genType); + groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings()); + processUsesAugments((DataNodeContainer) node, module); } - return generatedTypes; + return genType; } - /** - * Converts all lists of the module to the list of Type - * objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all lists - * @return list of Type which are generated from lists (objects - * of type ListSchemaNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • - *
- * - */ - private List allListsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() - + " cannot be NULL."); + private void containerToGenType(final Module module, final String basePackageName, + final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ContainerSchemaNode node) { + final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node); + if (genType != null) { + constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType); + resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes()); } + } - final List generatedTypes = new ArrayList<>(); - final DataNodeIterator it = new DataNodeIterator(module); - final List schemaLists = it.allLists(); - final String basePackageName = moduleNamespaceToPackageName(module); - if (schemaLists != null) { - for (final ListSchemaNode list : schemaLists) { - if (!list.isAddedByUses()) { - generatedTypes.addAll(listToGenType(basePackageName, list)); + private void listToGenType(final Module module, final String basePackageName, final GeneratedTypeBuilder parent, + final GeneratedTypeBuilder childOf, final ListSchemaNode node) { + final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node); + if (genType != null) { + constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), Types.listTypeFor(genType)); + + final List listKeys = listKeys(node); + final String packageName = packageNameForGeneratedType(basePackageName, node.getPath()); + final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node); + if (genTOBuilder != null) { + final Type identifierMarker = Types.parameterizedTypeFor(IDENTIFIER, genType); + final Type identifiableMarker = Types.parameterizedTypeFor(IDENTIFIABLE, genTOBuilder); + genTOBuilder.addImplementsType(identifierMarker); + genType.addImplementsType(identifiableMarker); + } + + for (DataSchemaNode schemaNode : node.getChildNodes()) { + if (!schemaNode.isAugmenting()) { + addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module); } } - } - return generatedTypes; - } - /** - * Converts all choices of the module to the list of - * Type objects. - * - * @param module - * module from which is obtained DataNodeIterator to iterate over - * all choices - * @return list of Type which are generated from choices - * (objects of type ChoiceNode) - * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • * - *
- * - */ - private List allChoicesToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + // serialVersionUID + if (genTOBuilder != null) { + final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); + prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder))); + genTOBuilder.setSUID(prop); + } - final DataNodeIterator it = new DataNodeIterator(module); - final List choiceNodes = it.allChoices(); - final String basePackageName = moduleNamespaceToPackageName(module); + typeBuildersToGenTypes(module, genType, genTOBuilder); + } + } - final List generatedTypes = new ArrayList<>(); - for (final ChoiceNode choice : choiceNodes) { - if ((choice != null) && !choice.isAddedByUses()) { - generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice)); + private void processUsesAugments(final DataNodeContainer node, final Module module) { + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + for (UsesNode usesNode : node.getUses()) { + for (AugmentationSchema augment : usesNode.getAugmentations()) { + usesAugmentationToGenTypes(basePackageName, augment, module, usesNode, node); + processUsesAugments(augment, module); } } - return generatedTypes; } /** @@ -389,31 +351,24 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained list of all augmentation objects * to iterate over them - * @return list of Type which are generated from augments - * (objects of type AugmentationSchema) * @throws IllegalArgumentException *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • + *
  • if the module is null
  • + *
  • if the name of module is null
  • *
- * + * @throws IllegalStateException + * if set of augmentations from module is null */ - private List allAugmentsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"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."); - } + private void allAugmentsToGenTypes(final Module module) { + checkArgument(module != null, "Module reference cannot be NULL."); + checkArgument(module.getName() != null, "Module name cannot be NULL."); + checkState(module.getAugmentations() != null, "Augmentations Set cannot be NULL."); - final List generatedTypes = new ArrayList<>(); - final String basePackageName = moduleNamespaceToPackageName(module); + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); final List augmentations = resolveAugmentations(module); - for (final AugmentationSchema augment : augmentations) { - generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment)); + for (AugmentationSchema augment : augmentations) { + augmentationToGenTypes(basePackageName, augment, module); } - return generatedTypes; } /** @@ -426,63 +381,39 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return list of sorted AugmentationSchema objects obtained * from module * @throws IllegalArgumentException - *
    - *
  • if the module equals null
  • - *
  • if the set of augmentation equals null
  • - *
- * + * if module is null + * @throws IllegalStateException + * if set of module augmentations is null */ private List resolveAugmentations(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkState(module.getAugmentations() != null,"Augmentations Set cannot be NULL."); + checkArgument(module != null, "Module reference cannot be NULL."); + checkState(module.getAugmentations() != null, "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; - - } - }); + List sortedAugmentations = new ArrayList<>(augmentations); + Collections.sort(sortedAugmentations, Comparators.AUGMENT_COMP); return sortedAugmentations; } /** - * Converts whole module to GeneratedType object. - * Firstly is created the module builder object from which is finally - * obtained reference to GeneratedType object. + * Create GeneratedTypeBuilder object from module argument. * * @param module - * module from which are obtained the module name, child nodes, - * uses and is derived package name - * @return GeneratedType which is internal representation of - * the module + * Module object from which builder will be created + * @return GeneratedTypeBuilder which is internal + * representation of the module * @throws IllegalArgumentException - * if the module equals null - * + * if module is null */ - private GeneratedType moduleToDataType(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + private GeneratedTypeBuilder moduleToDataType(final Module module) { + checkArgument(module != null, "Module reference cannot be NULL."); final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); - moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class)); - - final String basePackageName = moduleNamespaceToPackageName(module); - if (moduleDataTypeBuilder != null) { - final Set dataNodes = module.getChildNodes(); - resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes); - } - return moduleDataTypeBuilder.toInstance(); + moduleDataTypeBuilder.addImplementsType(DATA_ROOT); + moduleDataTypeBuilder.addComment(module.getDescription()); + return moduleDataTypeBuilder; } /** @@ -493,99 +424,64 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained set of all rpc objects to * iterate over them - * @return list of Type which are generated from rpcs inputs, - * outputs + container and lists which are part of inputs or outputs * @throws IllegalArgumentException *
    - *
  • if the module equals null
  • - *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • + *
  • if the module is null
  • + *
  • if the name of module is null
  • *
- * + * @throws IllegalStateException + * if set of rpcs from module is null */ - private List allRPCMethodsToGenType(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module " - + module.getName() + " cannot be NULL."); - } - - final String basePackageName = moduleNamespaceToPackageName(module); + private void rpcMethodsToGenType(final Module module) { + checkArgument(module != null, "Module reference cannot be NULL."); + checkArgument(module.getName() != null, "Module name cannot be NULL."); final Set rpcDefinitions = module.getRpcs(); - + checkState(rpcDefinitions != null, "Set of rpcs from module " + module.getName() + " cannot be NULL."); if (rpcDefinitions.isEmpty()) { - return Collections.emptyList(); + return; } - final List genRPCTypes = new ArrayList<>(); + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service"); interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class)); - final Type future = Types.typeForClass(Future.class); - for (final RpcDefinition rpc : rpcDefinitions) { + for (RpcDefinition rpc : rpcDefinitions) { if (rpc != null) { - - String rpcName = parseToClassName(rpc.getQName().getLocalName()); - String rpcMethodName = parseToValidParamName(rpcName); - MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName); - - final List rpcInOut = new ArrayList<>(); - - ContainerSchemaNode input = rpc.getInput(); - ContainerSchemaNode output = rpc.getOutput(); + final String rpcName = BindingMapping.getClassName(rpc.getQName()); + final String rpcMethodName = parseToValidParamName(rpcName); + final String rpcComment = rpc.getDescription(); + final MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName); + final ContainerSchemaNode input = rpc.getInput(); + final ContainerSchemaNode output = rpc.getOutput(); if (input != null) { - rpcInOut.add(new DataNodeIterator(input)); - GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); + final GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); addImplementedInterfaceFromUses(input, inType); inType.addImplementsType(DATA_OBJECT); inType.addImplementsType(augmentable(inType)); - resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes()); - Type inTypeInstance = inType.toInstance(); - genRPCTypes.add(inTypeInstance); + resolveDataSchemaNodes(module, basePackageName, inType, inType, input.getChildNodes()); + genCtx.get(module).addChildNodeType(input.getPath(), inType); + final GeneratedType inTypeInstance = inType.toInstance(); method.addParameter(inTypeInstance, "input"); } - Type outTypeInstance = Types.typeForClass(Void.class); + Type outTypeInstance = VOID; if (output != null) { - rpcInOut.add(new DataNodeIterator(output)); - GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); + final GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); addImplementedInterfaceFromUses(output, outType); outType.addImplementsType(DATA_OBJECT); outType.addImplementsType(augmentable(outType)); - - resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes()); + resolveDataSchemaNodes(module, basePackageName, outType, outType, output.getChildNodes()); + genCtx.get(module).addChildNodeType(output.getPath(), outType); outTypeInstance = outType.toInstance(); - genRPCTypes.add(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) { - if (!container.isAddedByUses()) { - genRPCTypes.add(containerToGenType(basePackageName, container)); - } - } - } - List nLists = it.allLists(); - if ((nLists != null) && !nLists.isEmpty()) { - for (final ListSchemaNode list : nLists) { - if (!list.isAddedByUses()) { - genRPCTypes.addAll(listToGenType(basePackageName, list)); - } - } - } - } + method.setComment(rpcComment); + method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes)); } } - genRPCTypes.add(interfaceBuilder.toInstance()); - return genRPCTypes; + + genCtx.get(module).addTopLevelNodeType(interfaceBuilder); } /** @@ -596,56 +492,47 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param module * module from which is obtained set of all notification objects * to iterate over them - * @return list of Type which are generated from notification - * (object of type NotificationDefinition * @throws IllegalArgumentException *
    *
  • if the module equals null
  • *
  • if the name of module equals null
  • - *
  • if the set of child nodes equals null
  • *
- * + * @throws IllegalStateException + * if set of notifications from module is null */ - private List allNotificationsToGenType(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Notification Definitions in module " - + module.getName() + " cannot be NULL."); + private void notificationsToGenType(final Module module) { + checkArgument(module != null, "Module reference cannot be NULL."); + checkArgument(module.getName() != null, "Module name cannot be NULL."); + final Set notifications = module.getNotifications(); + checkState(notifications != null, "Set of notification from module " + module.getName() + " cannot be NULL."); + if (notifications.isEmpty()) { + return; } - final String basePackageName = moduleNamespaceToPackageName(module); - final List genNotifyTypes = new ArrayList<>(); - final Set notifications = module.getNotifications(); + final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener"); + listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER); + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); - for (final NotificationDefinition notification : notifications) { + for (NotificationDefinition notification : notifications) { if (notification != null) { - DataNodeIterator it = new DataNodeIterator(notification); + processUsesAugments(notification, module); + + final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition(basePackageName, + notification, BindingTypes.DATA_OBJECT); + notificationInterface.addImplementsType(NOTIFICATION); + genCtx.get(module).addChildNodeType(notification.getPath(), notificationInterface); - // Containers - for (ContainerSchemaNode node : it.allContainers()) { - if (!node.isAddedByUses()) { - genNotifyTypes.add(containerToGenType(basePackageName, node)); - } - } - // Lists - for (ListSchemaNode node : it.allLists()) { - if (!node.isAddedByUses()) { - genNotifyTypes.addAll(listToGenType(basePackageName, node)); - } - } - final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName, - notification); - notificationTypeBuilder.addImplementsType(Types - .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class)); // Notification object - resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes()); - genNotifyTypes.add(notificationTypeBuilder.toInstance()); + resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface, + notification.getChildNodes()); + + listenerInterface.addMethod("on" + notificationInterface.getName()) + .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification") + .setComment(notification.getDescription()).setReturnType(Types.VOID); } } - return genNotifyTypes; + + genCtx.get(module).addTopLevelNodeType(listenerInterface); } /** @@ -658,23 +545,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param context * schema context only used as input parameter for method * {@link identityToGenType} - * @return list of Type which are generated from identities - * (object of type IdentitySchemaNode * */ - private List allIdentitiesToGenTypes(final Module module, final SchemaContext context) { - List genTypes = new ArrayList<>(); - + private void allIdentitiesToGenTypes(final Module module, final SchemaContext context) { final Set schemaIdentities = module.getIdentities(); - - final String basePackageName = moduleNamespaceToPackageName(module); + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); if (schemaIdentities != null && !schemaIdentities.isEmpty()) { - for (final IdentitySchemaNode identity : schemaIdentities) { - genTypes.add(identityToGenType(basePackageName, identity, context)); + for (IdentitySchemaNode identity : schemaIdentities) { + identityToGenType(module, basePackageName, identity, context); } } - return genTypes; } /** @@ -685,6 +566,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity * BaseIdentity} is added * + * @param module + * current module * @param basePackageName * string contains the module package name * @param identity @@ -693,66 +576,77 @@ public final class BindingGeneratorImpl implements BindingGenerator { * SchemaContext which is used to get package and name * information about base of identity * - * @return GeneratedType which is generated from identity (object of type - * IdentitySchemaNode - * */ - private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity, - final SchemaContext context) { + private void identityToGenType(final Module module, final String basePackageName, + final IdentitySchemaNode identity, final SchemaContext context) { if (identity == null) { - return null; + return; } - final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); - final String genTypeName = parseToClassName(identity.getQName().getLocalName()); + final String genTypeName = BindingMapping.getClassName(identity.getQName()); final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName); - - IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); - if (baseIdentity != null) { - Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); - - final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName()); - - GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); - newType.setExtendsType(gto); + final IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); + if (baseIdentity == null) { + final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.class.getPackage().getName(), + BaseIdentity.class.getSimpleName()); + newType.setExtendsType(gto.toInstance()); } else { - newType.setExtendsType(Types.getBaseIdentityTO()); + final Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); + final String returnTypePkgName = BindingMapping.getRootPackageName(baseIdentityParentModule + .getQNameModule()); + final String returnTypeName = BindingMapping.getClassName(baseIdentity.getQName()); + final GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName) + .toInstance(); + newType.setExtendsType(gto); } newType.setAbstract(true); - return newType.toInstance(); + newType.addComment(identity.getDescription()); + newType.setDescription(identity.getDescription()); + newType.setReference(identity.getReference()); + newType.setModuleName(module.getName()); + newType.setSchemaPath(identity.getPath().getPathFromRoot()); + + final QName qname = identity.getQName(); + qnameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, qname); + + genCtx.get(module).addIdentityType(identity.getQName(), newType); + } + + private static Constant qnameConstant(final GeneratedTypeBuilderBase toBuilder, final String constantName, + final QName name) { + StringBuilder sb = new StringBuilder("org.opendaylight.yangtools.yang.common.QName"); + sb.append(".create("); + sb.append('"'); + sb.append(name.getNamespace()); + sb.append("\",\""); + sb.append(name.getFormattedRevision()); + sb.append("\",\""); + sb.append(name.getLocalName()); + sb.append("\");"); + + return toBuilder.addConstant(typeForClass(QName.class), constantName, sb.toString()); } /** * Converts all groupings of the module to the list of * Type objects. Firstly are groupings sorted according mutual - * dependencies. At least dependend (indepedent) groupings are in the list + * dependencies. At least dependent (independent) groupings are in the list * saved at first positions. For every grouping the record is added to map * {@link BindingGeneratorImpl#allGroupings allGroupings} * * @param module - * module from which is obtained set of all grouping objects to - * iterate over them - * @return list of Type which are generated from groupings - * (object of type GroupingDefinition) + * current module + * @param collection + * of groupings from which types will be generated * */ - private List allGroupingsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module parameter can not be null"); - final List genTypes = new ArrayList<>(); - final String basePackageName = moduleNamespaceToPackageName(module); - final Set groupings = module.getGroupings(); - List groupingsSortedByDependencies; - - groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings); - - for (final GroupingDefinition grouping : groupingsSortedByDependencies) { - GeneratedType genType = groupingToGenType(basePackageName, grouping); - genTypes.add(genType); - SchemaPath schemaPath = grouping.getPath(); - allGroupings.put(schemaPath, genType); - } - return genTypes; + private void groupingsToGenTypes(final Module module, final Collection groupings) { + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + final List groupingsSortedByDependencies = new GroupingDefinitionDependencySort() + .sort(groupings); + for (GroupingDefinition grouping : groupingsSortedByDependencies) { + groupingToGenType(basePackageName, grouping, module); + } } /** @@ -764,42 +658,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { * string contains the module package name * @param grouping * GroupingDefinition which contains data about grouping + * @param module + * current module * @return GeneratedType which is generated from grouping (object of type * GroupingDefinition) */ - private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) { - if (grouping == null) { - return null; - } - + private void groupingToGenType(final String basePackageName, final GroupingDefinition grouping, final Module module) { final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath()); - final Set schemaNodes = grouping.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - return typeBuilder.toInstance(); - } - - /** - * Tries to find EnumTypeDefinition in typeDefinition. If base - * type of typeDefinition is of the type ExtendedType then this - * method is recursivelly called with this base type. - * - * @param typeDefinition - * TypeDefinition in which should be EnumTypeDefinition found as - * base type - * @return EnumTypeDefinition if it is found inside - * typeDefinition or null in other case - */ - private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition typeDefinition) { - if (typeDefinition != null) { - if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) { - return (EnumTypeDefinition) typeDefinition.getBaseType(); - } else if (typeDefinition.getBaseType() instanceof ExtendedType) { - return enumTypeDefFromExtendedType(typeDefinition.getBaseType()); - } - } - return null; + final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, grouping); + genCtx.get(module).addGroupingType(grouping.getPath(), genType); + resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.getChildNodes()); + groupingsToGenTypes(module, grouping.getGroupings()); + processUsesAugments(grouping, module); } /** @@ -816,18 +686,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { * builder * @param typeBuilder * GeneratedTypeBuilder to which will be enum builder assigned - * @return enumeration builder which contais data from + * @return enumeration builder which contains data from * enumTypeDef */ - private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, + private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final QName enumName, final GeneratedTypeBuilder typeBuilder) { if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null) && (enumTypeDef.getQName().getLocalName() != null)) { - - final String enumerationName = parseToClassName(enumName); + final String enumerationName = BindingMapping.getClassName(enumName); final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); + enumBuilder.setDescription(enumTypeDef.getDescription()); enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); - return enumBuilder; } return null; @@ -845,15 +714,19 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return instance of GeneratedTypeBuilder which represents * module. * @throws IllegalArgumentException - * if module equals null + * if module is null */ private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - String packageName = moduleNamespaceToPackageName(module); - final String moduleName = parseToClassName(module.getName()) + postfix; + checkArgument(module != null, "Module reference cannot be NULL."); + final String packageName = BindingMapping.getRootPackageName(module.getQNameModule()); + final String moduleName = BindingMapping.getClassName(module.getName()) + postfix; - return new GeneratedTypeBuilderImpl(packageName, moduleName); + final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName); + moduleBuilder.setDescription(module.getDescription()); + moduleBuilder.setReference(module.getReference()); + moduleBuilder.setModuleName(moduleName); + return moduleBuilder; } /** @@ -867,52 +740,146 @@ public final class BindingGeneratorImpl implements BindingGenerator { * string with the name of the package to which the augmentation * belongs * @param augSchema - * AugmentationSchema which is contains data about agumentation + * AugmentationSchema which is contains data about augmentation * (target path, childs...) - * @return list of Type objects which contains generated type - * for augmentation and for container, list and choice child nodes + * @param module + * current module + * @param parentUsesNode * @throws IllegalArgumentException *
    *
  • if augmentPackageName equals null
  • *
  • if augSchema equals null
  • - *
  • if target path of augSchema equals null
  • *
+ * @throws IllegalStateException + * if augment target path is null */ - private List augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) { - Preconditions.checkArgument(augmentPackageName != null,"Package Name cannot be NULL."); - Preconditions.checkArgument(augSchema != null,"Augmentation Schema cannot be NULL."); - Preconditions.checkState(augSchema.getTargetPath() != null,"Augmentation Schema does not contain Target Path (Target Path is NULL)."); + private void augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema, + final Module module) { + checkArgument(augmentPackageName != null, "Package Name cannot be NULL."); + checkArgument(augSchema != null, "Augmentation Schema cannot be NULL."); + checkState(augSchema.getTargetPath() != null, + "Augmentation Schema does not contain Target Path (Target Path is NULL)."); + + processUsesAugments(augSchema, module); + final SchemaPath targetPath = augSchema.getTargetPath(); + SchemaNode targetSchemaNode = null; + + targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + if (targetSchemaNode instanceof DataSchemaNode && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) { + if (targetSchemaNode instanceof DerivableSchemaNode) { + targetSchemaNode = ((DerivableSchemaNode) targetSchemaNode).getOriginal().orNull(); + } + if (targetSchemaNode == null) { + throw new IllegalStateException("Failed to find target node from grouping in augmentation " + augSchema + + " in module " + module.getName()); + } + } + if (targetSchemaNode == null) { + throw new IllegalArgumentException("augment target not found: " + targetPath); + } + + GeneratedTypeBuilder targetTypeBuilder = findChildNodeByPath(targetSchemaNode.getPath()); + if (targetTypeBuilder == null) { + targetTypeBuilder = findCaseByPath(targetSchemaNode.getPath()); + } + if (targetTypeBuilder == null) { + throw new NullPointerException("Target type not yet generated: " + targetSchemaNode); + } - final List genTypes = new ArrayList<>(); + if (!(targetSchemaNode instanceof ChoiceNode)) { + String packageName = augmentPackageName; + final Type targetType = new ReferencedTypeImpl(targetTypeBuilder.getPackageName(), + targetTypeBuilder.getName()); + addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, targetType, augSchema); + + } else { + generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance(), + (ChoiceNode) targetSchemaNode, augSchema.getChildNodes()); + } + } - // EVERY augmented interface will extends Augmentation interface - // and DataObject interface!!! + private void usesAugmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema, + final Module module, final UsesNode usesNode, final DataNodeContainer usesNodeParent) { + checkArgument(augmentPackageName != null, "Package Name cannot be NULL."); + checkArgument(augSchema != null, "Augmentation Schema cannot be NULL."); + checkState(augSchema.getTargetPath() != null, + "Augmentation Schema does not contain Target Path (Target Path is NULL)."); + + processUsesAugments(augSchema, module); final SchemaPath targetPath = augSchema.getTargetPath(); - final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); - if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null) - && (targetSchemaNode.getQName().getLocalName() != null)) { - final Module targetModule = findParentModule(schemaContext, targetSchemaNode); - final String targetBasePackage = moduleNamespaceToPackageName(targetModule); - final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); - final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); - final Set augChildNodes = augSchema.getChildNodes(); - - if (!(targetSchemaNode instanceof ChoiceNode)) { - final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, - targetPackageName, targetSchemaNodeName, augSchema); - final GeneratedType augType = augTypeBuilder.toInstance(); - genTypes.add(augType); - } else { - final Type refChoiceType = new ReferencedTypeImpl(targetPackageName, - parseToClassName(targetSchemaNodeName)); - final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode; - final Set choiceCaseNodes = choiceTarget.getCases(); - genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, - choiceCaseNodes)); + SchemaNode targetSchemaNode = findOriginalTargetFromGrouping(targetPath, usesNode); + if (targetSchemaNode == null) { + throw new IllegalArgumentException("augment target not found: " + targetPath); + } + + GeneratedTypeBuilder targetTypeBuilder = findChildNodeByPath(targetSchemaNode.getPath()); + if (targetTypeBuilder == null) { + targetTypeBuilder = findCaseByPath(targetSchemaNode.getPath()); + } + if (targetTypeBuilder == null) { + throw new NullPointerException("Target type not yet generated: " + targetSchemaNode); + } + + if (!(targetSchemaNode instanceof ChoiceNode)) { + String packageName = augmentPackageName; + if (usesNodeParent instanceof SchemaNode) { + packageName = packageNameForGeneratedType(augmentPackageName, ((SchemaNode) usesNodeParent).getPath(), + true); } - genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); + addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, targetTypeBuilder.toInstance(), + augSchema); + } else { + generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance(), + (ChoiceNode) targetSchemaNode, augSchema.getChildNodes()); } - return genTypes; + } + + /** + * Convenient method to find node added by uses statement. + * + * @param targetPath + * node path + * @param parentUsesNode + * parent of uses node + * @return node from its original location in grouping + */ + private DataSchemaNode findOriginalTargetFromGrouping(final SchemaPath targetPath, final UsesNode parentUsesNode) { + SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.getGroupingPath() + .getPathFromRoot()); + if (!(targetGrouping instanceof GroupingDefinition)) { + throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode); + } + + GroupingDefinition grouping = (GroupingDefinition) targetGrouping; + SchemaNode result = grouping; + for (QName node : targetPath.getPathFromRoot()) { + // finding by local name is valid, grouping cannot contain nodes + // with same name and different namespace + if (result instanceof DataNodeContainer) { + result = ((DataNodeContainer) result).getDataChildByName(node.getLocalName()); + } else if (result instanceof ChoiceNode) { + result = ((ChoiceNode) result).getCaseNodeByName(node.getLocalName()); + } + } + if (result == null) { + return null; + } + + boolean fromUses = ((DataSchemaNode) result).isAddedByUses(); + Iterator groupingUses = grouping.getUses().iterator(); + while (groupingUses.hasNext() && fromUses) { + result = findOriginalTargetFromGrouping(targetPath, groupingUses.next()); + if (result != null) { + fromUses = ((DataSchemaNode) result).isAddedByUses(); + } + } + if (fromUses) { + // this indicates invalid yang and thus possible bug in code because + // invalid yang should be already spotted by parser + throw new IllegalStateException("Failed to generate code for augment in " + parentUsesNode); + } + + return (DataSchemaNode) result; } /** @@ -921,22 +888,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { * The name of the type builder is equal to the name of augmented node with * serial number as suffix. * + * @param module + * current module * @param augmentPackageName * string with contains the package name to which the augment * belongs - * @param targetPackageName + * @param basePackageName * string with the package name to which the augmented node * belongs - * @param targetSchemaNodeName - * string with the name of the augmented node + * @param targetTypeRef + * target type * @param augSchema * augmentation schema which contains data about the child nodes * and uses of augment * @return generated type builder for augment */ - private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName, - final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) { - final String targetTypeName = parseToClassName(targetSchemaNodeName); + private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName, + final String basePackageName, final Type targetTypeRef, final AugmentationSchema augSchema) { Map augmentBuilders = genTypeBuilders.get(augmentPackageName); if (augmentBuilders == null) { augmentBuilders = new HashMap<>(); @@ -944,10 +912,12 @@ public final class BindingGeneratorImpl implements BindingGenerator { } final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes()); - final String augTypeName = augIdentifier != null ? parseToClassName(augIdentifier) : augGenTypeName( - augmentBuilders, targetTypeName); - final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName); - final Set augChildNodes = augSchema.getChildNodes(); + String augTypeName; + if (augIdentifier != null) { + augTypeName = BindingMapping.getClassName(augIdentifier); + } else { + augTypeName = augGenTypeName(augmentBuilders, targetTypeRef.getName()); + } final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); @@ -955,85 +925,29 @@ public final class BindingGeneratorImpl implements BindingGenerator { augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); addImplementedInterfaceFromUses(augSchema, augTypeBuilder); - augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); + augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.getChildNodes()); augmentBuilders.put(augTypeName, augTypeBuilder); + + genCtx.get(module).addTargetToAugmentation(targetTypeRef, augTypeBuilder); + genCtx.get(module).addAugmentType(augTypeBuilder); + genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema); return augTypeBuilder; } /** - * + * * @param unknownSchemaNodes - * @return + * @return nodeParameter of UnknownSchemaNode */ - private String getAugmentIdentifier(List unknownSchemaNodes) { - String ret = null; + private String getAugmentIdentifier(final List unknownSchemaNodes) { for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) { - QName nodeType = unknownSchemaNode.getNodeType(); + final QName nodeType = unknownSchemaNode.getNodeType(); if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName()) && YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) { return unknownSchemaNode.getNodeParameter(); } } - return ret; - } - - /** - * Convert a container, list and choice subnodes (and recursivelly their - * subnodes) of augment to generated types - * - * @param augBasePackageName - * string with the augment package name - * @param augChildNodes - * set of data schema nodes which represents child nodes of the - * augment - * - * @return list of Type which represents container, list and - * choice subnodes of augment - */ - 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)); - - if (childNode instanceof ContainerSchemaNode) { - genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode)); - } else if (childNode instanceof ListSchemaNode) { - genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode)); - } - } else if (childNode instanceof ChoiceNode) { - final ChoiceNode choice = (ChoiceNode) childNode; - for (final ChoiceCaseNode caseNode : choice.getCases()) { - augSchemaIts.add(new DataNodeIterator(caseNode)); - } - genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode)); - } - } - - for (final DataNodeIterator it : augSchemaIts) { - final List augContainers = it.allContainers(); - final List augLists = it.allLists(); - final List augChoices = it.allChoices(); - - if (augContainers != null) { - for (final ContainerSchemaNode container : augContainers) { - genTypes.add(containerToGenType(augBasePackageName, container)); - } - } - if (augLists != null) { - for (final ListSchemaNode list : augLists) { - genTypes.addAll(listToGenType(augBasePackageName, list)); - } - } - if (augChoices != null) { - for (final ChoiceNode choice : augChoices) { - genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice)); - } - } - } - return genTypes; + return null; } /** @@ -1049,40 +963,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return string with unique name for augmentation builder */ private String augGenTypeName(final Map builders, final String genTypeName) { - String augTypeName = genTypeName; - int index = 1; - while ((builders != null) && builders.containsKey(genTypeName + index)) { - index++; - } - augTypeName += index; - return augTypeName; - } - - /** - * Converts containerNode to generated type. Firstly the - * generated type builder is created. The subnodes of - * containerNode are added as methods and the instance of - * GeneratedType is returned. - * - * @param basePackageName - * string contains the module package name - * @param containerNode - * container schema node with the data about childs nodes and - * schema paths - * @return generated type for containerNode - */ - private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) { - if (containerNode == null) { - return null; + if (builders != null) { + while (builders.containsKey(genTypeName + index)) { + index = index + 1; + } } - - final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); - final Set schemaNodes = containerNode.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); - - resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); - return typeBuilder.toInstance(); + return genTypeName + index; } /** @@ -1092,13 +979,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { * The subnodes aren't mapped to the methods if they are part of grouping or * augment (in this case are already part of them). * + * @param module + * current module * @param basePackageName * string contains the module package name - * @param typeBuilder + * @param parent * generated type builder which represents any node. The subnodes * of this node are added to the typeBuilder as * methods. The subnode can be of type leaf, leaf-list, list, * container, choice. + * @param childOf + * parent type * @param schemaNodes * set of data schema nodes which are the children of the node * for which typeBuilder was created @@ -1106,23 +997,24 @@ public final class BindingGeneratorImpl implements BindingGenerator { * parameter. The getter methods (representing child nodes) could be * added to it. */ - 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() || schemaNode.isAddedByUses()) { - continue; + private GeneratedTypeBuilder resolveDataSchemaNodes(final Module module, final String basePackageName, + final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final Iterable schemaNodes) { + if (schemaNodes != null && parent != null) { + for (DataSchemaNode schemaNode : schemaNodes) { + if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module); } - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); } } - return typeBuilder; + return parent; } /** * Adds the methods to typeBuilder what represents subnodes of * node for which typeBuilder was created. * + * @param module + * current module * @param basePackageName * string contains the module package name * @param typeBuilder @@ -1130,6 +1022,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { * of this node are added to the typeBuilder as * methods. The subnode can be of type leaf, leaf-list, list, * container, choice. + * @param childOf + * parent type * @param schemaNodes * set of data schema nodes which are the children of the node * for which typeBuilder was created @@ -1137,12 +1031,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { * parameter typeBuilder. The getter method could be * added to it. */ - private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { + private GeneratedTypeBuilder augSchemaNodeToMethods(final Module module, final String basePackageName, + final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, + final Iterable schemaNodes) { if ((schemaNodes != null) && (typeBuilder != null)) { - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting()) { - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); + for (DataSchemaNode schemaNode : schemaNodes) { + if (!schemaNode.isAugmenting()) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module); } } } @@ -1155,69 +1050,38 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * @param basePackageName * string with the module package name - * @param schemaNode + * @param node * data schema node which is added to typeBuilder as * a method * @param typeBuilder * generated type builder to which is schemaNode * added as a method. + * @param childOf + * parent type + * @param module + * current module */ - 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); - } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); - } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); - } else if (schemaNode instanceof ChoiceNode) { - resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode); + private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode node, + final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Module module) { + if (node != null && typeBuilder != null) { + if (node instanceof LeafSchemaNode) { + resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) node); + } else if (node instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) node); + } else if (node instanceof ContainerSchemaNode) { + containerToGenType(module, basePackageName, typeBuilder, childOf, (ContainerSchemaNode) node); + } else if (node instanceof ListSchemaNode) { + listToGenType(module, basePackageName, typeBuilder, childOf, (ListSchemaNode) node); + } else if (node instanceof ChoiceNode) { + choiceToGeneratedType(module, basePackageName, typeBuilder, (ChoiceNode) node); + } else { + // TODO: anyxml not yet supported + LOG.debug("Unable to add schema node {} as method in {}: unsupported type of node.", node.getClass(), + typeBuilder.getFullyQualifiedName()); } } } - /** - * Creates a getter method for a choice node. - * - * Firstly generated type builder for choice is created or found in - * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name - * in the builder is created as concatenation of module package name and - * names of all parent nodes. In the end the getter method for choice is - * added to typeBuilder and return type is set to choice - * builder. - * - * @param basePackageName - * string with the module package name - * @param typeBuilder - * generated type builder to which is choiceNode - * added as getter method - * @param choiceNode - * choice node which is mapped as a getter method - * @throws IllegalArgumentException - *
    - *
  • if basePackageName equals null
  • - *
  • if typeBuilder equals null
  • - *
  • if choiceNode equals null
  • - *
- * - */ - private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ChoiceNode choiceNode) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); - Preconditions.checkArgument(choiceNode != null,"Choice Schema Node cannot be NULL."); - - final String choiceName = choiceNode.getQName().getLocalName(); - if (choiceName != null && !choiceNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); - final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); - constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType); - } - } - /** * Converts choiceNode to the list of generated types for * choice and its cases. @@ -1226,37 +1090,35 @@ public final class BindingGeneratorImpl implements BindingGenerator { * concatenation of the module package (basePackageName) and * names of all parents node. * + * @param module + * current module * @param basePackageName * string with the module package name + * @param parent + * parent type * @param choiceNode * choice node which is mapped to generated type. Also child * nodes - cases are mapped to generated types. - * @return list of generated types which contains generated type for choice - * and generated types for all cases which aren't added do choice - * through uses. * @throws IllegalArgumentException *
    - *
  • if basePackageName equals null
  • - *
  • if choiceNode equals null
  • + *
  • if basePackageName is null
  • + *
  • if choiceNode is null
  • *
- * */ - private List choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(choiceNode != null,"Choice Schema Node cannot be NULL."); + private void choiceToGeneratedType(final Module module, final String basePackageName, + final GeneratedTypeBuilder parent, final ChoiceNode choiceNode) { + checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); + checkArgument(choiceNode != null, "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(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)); + if (!choiceNode.isAddedByUses()) { + final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); + final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); + constructGetter(parent, choiceNode.getQName().getLocalName(), choiceNode.getDescription(), + choiceTypeBuilder); + choiceTypeBuilder.addImplementsType(typeForClass(DataContainer.class)); + genCtx.get(module).addChildNodeType(choiceNode.getPath(), choiceTypeBuilder); + generateTypesFromChoiceCases(module, basePackageName, choiceTypeBuilder.toInstance(), choiceNode); } - return generatedTypes; } /** @@ -1270,12 +1132,14 @@ public final class BindingGeneratorImpl implements BindingGenerator { * concrete case. There is also relation "implements type" * between every case builder and choice type * + * @param module + * current module * @param basePackageName * string with the module package name * @param refChoiceType * type which represents superior case - * @param caseNodes - * set of choice case nodes which are mapped to generated types + * @param choiceNode + * choice case node which is mapped to generated type * @return list of generated types for caseNodes. * @throws IllegalArgumentException *
    @@ -1283,79 +1147,136 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • if refChoiceType equals null
  • *
  • if caseNodes equals null
  • *
- * * */ - private List generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType, - final Set caseNodes) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); - Preconditions.checkArgument(caseNodes != null,"Set of Choice Case Nodes cannot be NULL."); - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceCaseNode caseNode : caseNodes) { + private void generateTypesFromChoiceCases(final Module module, final String basePackageName, + final Type refChoiceType, final ChoiceNode choiceNode) { + checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); + checkArgument(refChoiceType != null, "Referenced Choice Type cannot be NULL."); + checkArgument(choiceNode != null, "ChoiceNode cannot be NULL."); + + final Set caseNodes = choiceNode.getCases(); + if (caseNodes == null) { + return; + } + + for (ChoiceCaseNode caseNode : caseNodes) { if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { 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); + genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder); + genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode); + final Iterable caseChildNodes = caseNode.getChildNodes(); + if (caseChildNodes != null) { + Object parentNode = null; + final SchemaPath nodeSp = choiceNode.getPath(); + parentNode = findDataSchemaNode(schemaContext, nodeSp.getParent()); + + SchemaNode parent; + if (parentNode instanceof AugmentationSchema) { + final AugmentationSchema augSchema = (AugmentationSchema) parentNode; + final SchemaPath targetPath = augSchema.getTargetPath(); + SchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + if (targetSchemaNode instanceof DataSchemaNode + && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) { + if (targetSchemaNode instanceof DerivableSchemaNode) { + targetSchemaNode = ((DerivableSchemaNode) targetSchemaNode).getOriginal().orNull(); + } + if (targetSchemaNode == null) { + throw new IllegalStateException( + "Failed to find target node from grouping for augmentation " + augSchema + + " in module " + module.getName()); + } + } + parent = targetSchemaNode; + } else { + final SchemaPath sp = choiceNode.getPath(); + parent = findDataSchemaNode(schemaContext, sp.getParent()); + } + GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.getPath()); + if (childOfType == null) { + childOfType = findGroupingByPath(parent.getPath()); + } + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes); } - generatedTypes.add(caseTypeBuilder.toInstance()); } - } - return generatedTypes; + processUsesAugments(caseNode, module); + } } /** * Generates list of generated types for all the cases of a choice which are * added to the choice through the augment. * - * + * @param module + * current module * @param basePackageName * string contains name of package to which augment belongs. If * an augmented choice is from an other package (pcg1) than an * augmenting choice (pcg2) then case's of the augmenting choice * will belong to pcg2. - * @param refChoiceType - * Type which represents the choice to which case belongs. Every - * case has to contain its choice in extend part. - * @param caseNodes + * @param targetType + * Type which represents target choice + * @param targetNode + * node which represents target choice + * @param augmentedNodes * set of choice case nodes for which is checked if are/aren't * added to choice through augmentation * @return list of generated types which represents augmented cases of * choice refChoiceType * @throws IllegalArgumentException *
    - *
  • if basePackageName equals null
  • - *
  • if refChoiceType equals null
  • - *
  • if caseNodes equals null
  • + *
  • if basePackageName is null
  • + *
  • if targetType is null
  • + *
  • if augmentedNodes is null
  • *
*/ - private List generateTypesFromAugmentedChoiceCases(final String basePackageName, - final Type refChoiceType, final Set caseNodes) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); - Preconditions.checkArgument(caseNodes != null,"Set of Choice Case Nodes cannot be NULL."); - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceCaseNode caseNode : caseNodes) { - if (caseNode != null && caseNode.isAugmenting()) { + private void generateTypesFromAugmentedChoiceCases(final Module module, final String basePackageName, + final Type targetType, final ChoiceNode targetNode, final Iterable augmentedNodes) { + checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); + checkArgument(targetType != null, "Referenced Choice Type cannot be NULL."); + checkArgument(augmentedNodes != null, "Set of Choice Case Nodes cannot be NULL."); + + for (DataSchemaNode caseNode : augmentedNodes) { + if (caseNode != null) { final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); - caseTypeBuilder.addImplementsType(refChoiceType); + caseTypeBuilder.addImplementsType(targetType); + + SchemaNode parent = null; + final SchemaPath nodeSp = targetNode.getPath(); + parent = findDataSchemaNode(schemaContext, nodeSp.getParent()); + + GeneratedTypeBuilder childOfType = null; + if (parent instanceof Module) { + childOfType = genCtx.get(parent).getModuleNode(); + } else if (parent instanceof ChoiceCaseNode) { + childOfType = findCaseByPath(parent.getPath()); + } else if (parent instanceof DataSchemaNode || parent instanceof NotificationDefinition) { + childOfType = findChildNodeByPath(parent.getPath()); + } else if (parent instanceof GroupingDefinition) { + childOfType = findGroupingByPath(parent.getPath()); + } - final Set childNodes = caseNode.getChildNodes(); + if (childOfType == null) { + throw new IllegalArgumentException("Failed to find parent type of choice " + targetNode); + } + + ChoiceCaseNode node = null; + if (caseNode instanceof ChoiceCaseNode) { + node = (ChoiceCaseNode) caseNode; + } else { + node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName()); + } + final Iterable childNodes = node.getChildNodes(); if (childNodes != null) { - resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes); } - generatedTypes.add(caseTypeBuilder.toInstance()); + genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder); + genCtx.get(module).addChoiceToCaseMapping(targetType, caseTypeBuilder, node); } } - - return generatedTypes; } /** @@ -1375,7 +1296,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • true - in other cases
  • * */ - private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { + private Type resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { + Type returnType = null; if ((leaf != null) && (typeBuilder != null)) { final String leafName = leaf.getQName().getLocalName(); String leafDesc = leaf.getDescription(); @@ -1387,34 +1309,129 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (leafName != null && !leaf.isAddedByUses()) { final TypeDefinition typeDef = leaf.getType(); - Type returnType = null; + GeneratedTOBuilder genTOBuilder; if (typeDef instanceof EnumTypeDefinition) { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); - final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef); - final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef; + final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(), typeBuilder); if (enumBuilder != null) { - returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); + returnType = enumBuilder.toInstance(typeBuilder); } ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); } else if (typeDef instanceof UnionType) { - GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, parentModule); + genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule); if (genTOBuilder != null) { - returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule); } } else if (typeDef instanceof BitsTypeDefinition) { - GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, parentModule); + genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule); if (genTOBuilder != null) { returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); } } else { - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); + final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions); } if (returnType != null) { - constructGetter(typeBuilder, leafName, leafDesc, returnType); - return true; + final MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType); + processContextRefExtension(leaf, getter, parentModule); + } + } + } + return returnType; + } + + private void processContextRefExtension(final LeafSchemaNode leaf, final MethodSignatureBuilder getter, + final Module module) { + for (UnknownSchemaNode node : leaf.getUnknownSchemaNodes()) { + final QName nodeType = node.getNodeType(); + if ("context-reference".equals(nodeType.getLocalName())) { + final String nodeParam = node.getNodeParameter(); + IdentitySchemaNode identity = null; + String basePackageName = null; + final Iterable splittedElement = Splitter.on(':').split(nodeParam); + final Iterator iterator = splittedElement.iterator(); + final int length = Iterables.size(splittedElement); + if (length == 1) { + identity = findIdentityByName(module.getIdentities(), iterator.next()); + basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + } else if (length == 2) { + String prefix = iterator.next(); + final Module dependentModule = findModuleFromImports(module.getImports(), prefix); + if (dependentModule == null) { + throw new IllegalArgumentException("Failed to process context-reference: unknown prefix " + + prefix); + } + identity = findIdentityByName(dependentModule.getIdentities(), iterator.next()); + basePackageName = BindingMapping.getRootPackageName(dependentModule.getQNameModule()); + } else { + throw new IllegalArgumentException("Failed to process context-reference: unknown identity " + + nodeParam); } + if (identity == null) { + throw new IllegalArgumentException("Failed to process context-reference: unknown identity " + + nodeParam); + } + + final Class clazz = RoutingContext.class; + final AnnotationTypeBuilder rc = getter.addAnnotation(clazz.getPackage().getName(), + clazz.getSimpleName()); + final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); + final String genTypeName = BindingMapping.getClassName(identity.getQName().getLocalName()); + rc.addParameter("value", packageName + "." + genTypeName + ".class"); + } + } + } + + private IdentitySchemaNode findIdentityByName(final Set identities, final String name) { + for (IdentitySchemaNode id : identities) { + if (id.getQName().getLocalName().equals(name)) { + return id; + } + } + return null; + } + + private Module findModuleFromImports(final Set imports, final String prefix) { + for (ModuleImport imp : imports) { + if (imp.getPrefix().equals(prefix)) { + return schemaContext.findModuleByName(imp.getModuleName(), imp.getRevision()); + } + } + return null; + } + + private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, + final boolean isReadOnly, final Module module) { + if ((leaf != null) && (toBuilder != null)) { + final String leafName = leaf.getQName().getLocalName(); + String leafDesc = leaf.getDescription(); + if (leafDesc == null) { + leafDesc = ""; + } + + if (leafName != null) { + Type returnType = null; + final TypeDefinition typeDef = leaf.getType(); + if (typeDef instanceof UnionTypeDefinition) { + // GeneratedType for this type definition should be already + // created + QName qname = typeDef.getQName(); + Module unionModule = null; + String prefix = qname.getPrefix(); + if (prefix == null || prefix.isEmpty() || prefix.equals(module.getPrefix())) { + unionModule = module; + } else { + unionModule = findModuleFromImports(module.getImports(), qname.getPrefix()); + } + final ModuleContext mc = genCtx.get(unionModule); + returnType = mc.getTypedefs().get(typeDef.getPath()); + } else { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + } + return resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly); } } return false; @@ -1430,6 +1447,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param leaf * leaf schema node which is added to toBuilder as * property + * @param returnType + * property type * @param isReadOnly * boolean value which says if leaf property is|isn't read only * @return boolean value @@ -1440,36 +1459,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { * */ private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, - boolean isReadOnly) { - if ((leaf != null) && (toBuilder != null)) { - final String leafName = leaf.getQName().getLocalName(); - String leafDesc = leaf.getDescription(); - if (leafDesc == null) { - leafDesc = ""; - } - - if (leafName != null && !leaf.isAddedByUses()) { - final TypeDefinition typeDef = leaf.getType(); - - // TODO: properly resolve enum types - final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); - - if (returnType != null) { - final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName)); - - propBuilder.setReadOnly(isReadOnly); - propBuilder.setReturnType(returnType); - propBuilder.setComment(leafDesc); - - toBuilder.addEqualsIdentity(propBuilder); - toBuilder.addHashIdentity(propBuilder); - toBuilder.addToStringProperty(propBuilder); - - return true; - } - } + final Type returnType, final boolean isReadOnly) { + if (returnType == null) { + return false; } - return false; + final String leafName = leaf.getQName().getLocalName(); + final String leafDesc = leaf.getDescription(); + final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToValidParamName(leafName)); + propBuilder.setReadOnly(isReadOnly); + propBuilder.setReturnType(returnType); + propBuilder.setComment(leafDesc); + toBuilder.addEqualsIdentity(propBuilder); + toBuilder.addHashIdentity(propBuilder); + toBuilder.addToStringProperty(propBuilder); + return true; } /** @@ -1491,104 +1494,77 @@ public final class BindingGeneratorImpl implements BindingGenerator { */ private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) { if ((node != null) && (typeBuilder != null)) { - final String nodeName = node.getQName().getLocalName(); - String nodeDesc = node.getDescription(); - if (nodeDesc == null) { - nodeDesc = ""; - } + final QName nodeName = node.getQName(); if (nodeName != null && !node.isAddedByUses()) { - final TypeDefinition type = node.getType(); - final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type)); + final TypeDefinition typeDef = node.getType(); + final Module parentModule = findParentModule(schemaContext, node); - constructGetter(typeBuilder, nodeName, nodeDesc, listType); + Type returnType = null; + if (typeDef instanceof EnumTypeDefinition) { + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node); + final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef; + final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, + typeBuilder); + returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); + ((TypeProviderImpl) typeProvider).putReferencedType(node.getPath(), returnType); + } else if (typeDef instanceof UnionType) { + final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule); + if (genTOBuilder != null) { + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule); + } + } else if (typeDef instanceof BitsTypeDefinition) { + final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule); + returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + } else { + final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions); + } + + final ParameterizedType listType = Types.listTypeFor(returnType); + constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType); return true; } } return false; } - /** - * Creates a getter method for a container node. - * - * Firstly generated type builder for container is created or found in - * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name - * in the builder is created as concatenation of module package name and - * names of all parent nodes. In the end the getter method for container is - * added to typeBuilder and return type is set to container - * type builder. - * - * @param basePackageName - * string with the module package name - * @param typeBuilder - * generated type builder to which is containerNode - * added as getter method - * @param containerNode - * container schema node which is mapped as getter method to - * typeBuilder - * @return boolean value - *
      - *
    • false - if containerNode, - * typeBuilder, container node name equal null or - * containerNode is added by uses
    • - *
    • true - other cases
    • - *
    - */ - 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 && !containerNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); - - final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); - constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType); - - return true; - } + private Type createReturnTypeForUnion(final GeneratedTOBuilder genTOBuilder, final TypeDefinition typeDef, + final GeneratedTypeBuilder typeBuilder, final Module parentModule) { + final GeneratedTOBuilderImpl returnType = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(), + genTOBuilder.getName()); + + returnType.setDescription(typeDef.getDescription()); + returnType.setReference(typeDef.getReference()); + returnType.setSchemaPath(typeDef.getPath().getPathFromRoot()); + returnType.setModuleName(parentModule.getName()); + + genTOBuilder.setTypedef(true); + genTOBuilder.setIsUnion(true); + ((TypeProviderImpl) typeProvider).addUnitsToGenTO(genTOBuilder, typeDef.getUnits()); + + // union builder + final GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(), + genTOBuilder.getName() + "Builder"); + unionBuilder.setIsUnionBuilder(true); + final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance"); + method.setReturnType(returnType); + method.addParameter(Types.STRING, "defaultValue"); + method.setAccessModifier(AccessModifier.PUBLIC); + method.setStatic(true); + + final Set types = ((TypeProviderImpl) typeProvider).getAdditionalTypes().get(parentModule); + if (types == null) { + ((TypeProviderImpl) typeProvider).getAdditionalTypes().put(parentModule, + Sets. newHashSet(unionBuilder.toInstance())); + } else { + types.add(unionBuilder.toInstance()); } - return false; + return returnType.toInstance(); } - /** - * Creates a getter method for a list node. - * - * Firstly generated type builder for list is created or found in - * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name - * in the builder is created as concatenation of module package name and - * names of all parent nodes. In the end the getter method for list is added - * to typeBuilder and return type is set to list type builder. - * - * @param basePackageName - * string with the module package name - * @param typeBuilder - * generated type builder to which is added as - * getter method - * @param listNode - * list schema node which is mapped as getter method to - * typeBuilder - * @return boolean value - *
      - *
    • false - if listNode, typeBuilder, - * list node name equal null or listNode is added by - * uses
    • - *
    • true - other cases
    • - *
    - */ - private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ListSchemaNode listNode) { - if ((listNode != null) && (typeBuilder != null)) { - final String listName = listNode.getQName().getLocalName(); - - if (listName != null && !listNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, listNode.getPath()); - final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, listNode); - constructGetter(typeBuilder, listName, listNode.getDescription(), Types.listTypeFor(rawGenType)); - return true; - } - } - return false; + private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { + return addDefaultInterfaceDefinition(packageName, schemaNode, null); } /** @@ -1610,20 +1586,27 @@ public final class BindingGeneratorImpl implements BindingGenerator { * schemaNode belongs. * @param schemaNode * schema node for which is created generated type builder + * @param parent + * parent type (can be null) * @return generated type builder schemaNode */ - private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { - final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, ""); - builder.addImplementsType(DATA_OBJECT); + private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode, + final Type parent) { + final GeneratedTypeBuilder it = addRawInterfaceDefinition(packageName, schemaNode, ""); + if (parent == null) { + it.addImplementsType(DATA_OBJECT); + } else { + it.addImplementsType(BindingTypes.childOf(parent)); + } if (!(schemaNode instanceof GroupingDefinition)) { - builder.addImplementsType(augmentable(builder)); + it.addImplementsType(augmentable(it)); } if (schemaNode instanceof DataNodeContainer) { - addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder); + addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, it); } - return builder; + return it; } /** @@ -1653,32 +1636,44 @@ public final class BindingGeneratorImpl implements BindingGenerator { * builder belongs * @param schemaNode * schema node which provide data about the schema node name + * @param prefix + * return type name prefix * @return generated type builder for schemaNode * @throws IllegalArgumentException *
      - *
    • if schemaNode equals null
    • - *
    • if packageName equals null
    • - *
    • if Q name of schema node is null
    • - *
    • if schema node name is nul
    • + *
    • if schemaNode is null
    • + *
    • if packageName is null
    • + *
    • if QName of schema node is null
    • + *
    • if schemaNode name is null
    • *
    * */ private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode, final String prefix) { - Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); - Preconditions.checkArgument(packageName != null,"Package Name for Generated Type cannot be NULL."); - Preconditions.checkArgument(schemaNode.getQName() != null,"QName for Data Schema Node cannot be NULL."); + checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); + checkArgument(packageName != null, "Package Name for Generated Type cannot be NULL."); + checkArgument(schemaNode.getQName() != null, "QName for Data Schema Node cannot be NULL."); final String schemaNodeName = schemaNode.getQName().getLocalName(); - Preconditions.checkArgument(schemaNodeName != null,"Local Name of QName for Data Schema Node cannot be NULL."); + checkArgument(schemaNodeName != null, "Local Name of QName for Data Schema Node cannot be NULL."); - final String genTypeName; + String genTypeName; if (prefix == null) { - genTypeName = parseToClassName(schemaNodeName); + genTypeName = BindingMapping.getClassName(schemaNodeName); } else { - genTypeName = prefix + parseToClassName(schemaNodeName); + genTypeName = prefix + BindingMapping.getClassName(schemaNodeName); } - final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + // FIXME: Validation of name conflict + final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + qnameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName()); + newType.addComment(schemaNode.getDescription()); + newType.setDescription(schemaNode.getDescription()); + newType.setReference(schemaNode.getReference()); + newType.setSchemaPath(schemaNode.getPath().getPathFromRoot()); + + final Module module = findParentModule(schemaContext, schemaNode); + newType.setModuleName(module.getName()); + if (!genTypeBuilders.containsKey(packageName)) { final Map builders = new HashMap<>(); builders.put(genTypeName, newType); @@ -1693,32 +1688,24 @@ public final class BindingGeneratorImpl implements BindingGenerator { } /** - * Creates the name of the getter method from methodName. + * Creates the name of the getter method name from localName. * - * @param methodName + * @param localName * string with the name of the getter method + * @param returnType + * return type * @return string with the name of the getter method for * methodName in JAVA method format */ - private String getterMethodName(final String methodName) { + public static String getterMethodName(final String localName, final Type returnType) { final StringBuilder method = new StringBuilder(); - method.append("get"); - method.append(parseToClassName(methodName)); - return method.toString(); - } - - /** - * Creates the name of the setter method from methodName. - * - * @param methodName - * string with the name of the setter method - * @return string with the name of the setter method for - * methodName in JAVA method format - */ - private String setterMethodName(final String methodName) { - final StringBuilder method = new StringBuilder(); - method.append("set"); - method.append(parseToClassName(methodName)); + if (BOOLEAN.equals(returnType)) { + method.append("is"); + } else { + method.append("get"); + } + String name = BindingMapping.toFirstUpper(BindingMapping.getPropertyName(localName)); + method.append(name); return method.toString(); } @@ -1745,79 +1732,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { */ private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder, final String schemaNodeName, final String comment, final Type returnType) { - final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName)); - + final MethodSignatureBuilder getMethod = interfaceBuilder + .addMethod(getterMethodName(schemaNodeName, returnType)); getMethod.setComment(comment); getMethod.setReturnType(returnType); - return getMethod; } - /** - * Creates a method signature builder as a part of - * interfaceBuilder for schemaNodeName - * - * The method signature builder is created for the setter method of - * schemaNodeName. Also comment - * parameterType data are added to the builder. The return type - * of the method is set to void. - * - * @param interfaceBuilder - * generated type builder for which the setter method should be - * created - * @param schemaNodeName - * string with schema node name. The name will be the part of the - * setter method name. - * @param comment - * string with comment for the setter method - * @param parameterType - * type which represents the type of the setter method input - * parameter - * @return method signature builder which represents the setter method of - * interfaceBuilder - */ - 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.setReturnType(Types.voidType()); - - return setMethod; - } - - private List listToGenType(final String basePackageName, final ListSchemaNode list) { - Preconditions.checkArgument(basePackageName != null,"Package Name for Generated Type cannot be NULL."); - Preconditions.checkArgument(list != null,"List Schema Node cannot be NULL."); - - final String packageName = packageNameForGeneratedType(basePackageName, list.getPath()); - // final GeneratedTypeBuilder typeBuilder = - // resolveListTypeBuilder(packageName, list); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, list); - - final List listKeys = listKeys(list); - GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list); - - if (genTOBuilder != null) { - ParameterizedType identifierMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifier.class), - typeBuilder); - ParameterizedType identifiableMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class), - genTOBuilder); - genTOBuilder.addImplementsType(identifierMarker); - typeBuilder.addImplementsType(identifiableMarker); - } - final Set schemaNodes = list.getChildNodes(); - - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting()) { - continue; - } - addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); - } - return typeBuildersToGenTypes(typeBuilder, genTOBuilder); - } - /** * Adds schemaNode to typeBuilder as getter method * or to genTOBuilder as property. @@ -1834,6 +1755,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { * generated TO builder for the list keys * @param listKeys * list of string which contains names of the list keys + * @param module + * current module * @throws IllegalArgumentException *
      *
    • if schemaNode equals null
    • @@ -1841,39 +1764,44 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
    */ private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode, - final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys) { - Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); - - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); + final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys, + final Module module) { + checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); + checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); if (schemaNode instanceof LeafSchemaNode) { final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode; final String leafName = leaf.getQName().getLocalName(); - if (!listKeys.contains(leafName)) { - resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); - } else { - resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); + final Type type = resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); + if (listKeys.contains(leafName)) { + if (type == null) { + resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module); + } else { + resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, type, true); + } + } + } else if (!schemaNode.isAddedByUses()) { + if (schemaNode instanceof LeafListSchemaNode) { + resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); + } else if (schemaNode instanceof ContainerSchemaNode) { + containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode); + } else if (schemaNode instanceof ChoiceNode) { + choiceToGeneratedType(module, basePackageName, typeBuilder, (ChoiceNode) schemaNode); + } else if (schemaNode instanceof ListSchemaNode) { + listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode); } - } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); - } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); } } - private List typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { - final List genTypes = new ArrayList<>(); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); + private void typeBuildersToGenTypes(final Module module, final GeneratedTypeBuilder typeBuilder, + final GeneratedTOBuilder genTOBuilder) { + checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); if (genTOBuilder != null) { - final GeneratedTransferObject genTO = genTOBuilder.toInstance(); + GeneratedTransferObject genTO = genTOBuilder.toInstance(); constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); - genTypes.add(genTO); + genCtx.get(module).addGeneratedTOBuilder(genTOBuilder); } - genTypes.add(typeBuilder.toInstance()); - return genTypes; } /** @@ -1889,11 +1817,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { private List listKeys(final ListSchemaNode list) { final List listKeys = new ArrayList<>(); - if (list.getKeyDefinition() != null) { - final List keyDefinitions = list.getKeyDefinition(); - - for (final QName keyDefinition : keyDefinitions) { - listKeys.add(keyDefinition.getLocalName()); + List keyDefinition = list.getKeyDefinition(); + if (keyDefinition != null) { + for (QName keyDef : keyDefinition) { + listKeys.add(keyDef.getLocalName()); } } return listKeys; @@ -1914,13 +1841,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list) { GeneratedTOBuilder genTOBuilder = null; if ((list.getKeyDefinition() != null) && (!list.getKeyDefinition().isEmpty())) { - if (list != null) { - final String listName = list.getQName().getLocalName() + "Key"; - genTOBuilder = schemaNodeToTransferObjectBuilder(packageName, listName); - } + final String listName = list.getQName().getLocalName() + "Key"; + final String genTOName = BindingMapping.getClassName(listName); + genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName); } return genTOBuilder; - } /** @@ -1933,7 +1858,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { * If more then one generated TO builder is created for enclosing then all * of the generated TO builders are added to typeBuilder as * enclosing transfer objects. - * + * * @param typeDef * type definition which can be of type UnionType or * BitsTypeDefinition @@ -1942,19 +1867,37 @@ public final class BindingGeneratorImpl implements BindingGenerator { * from typeDef * @param leafName * string with name for generated TO builder + * @param leaf * @return generated TO builder for typeDef */ - private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, - String leafName, Module parentModule) { - final String classNameFromLeaf = parseToClassName(leafName); - List genTOBuilders = new ArrayList<>(); + private GeneratedTOBuilder addTOToTypeBuilder(final TypeDefinition typeDef, + final GeneratedTypeBuilder typeBuilder, final DataSchemaNode leaf, final Module parentModule) { + final String classNameFromLeaf = BindingMapping.getClassName(leaf.getQName()); + final List genTOBuilders = new ArrayList<>(); final String packageName = typeBuilder.getFullyQualifiedName(); if (typeDef instanceof UnionTypeDefinition) { - genTOBuilders.addAll(((TypeProviderImpl) typeProvider).provideGeneratedTOBuildersForUnionTypeDef( - packageName, typeDef, classNameFromLeaf)); + final List types = ((TypeProviderImpl) typeProvider) + .provideGeneratedTOBuildersForUnionTypeDef(packageName, ((UnionTypeDefinition) typeDef), + classNameFromLeaf, leaf); + genTOBuilders.addAll(types); + + GeneratedTOBuilder resultTOBuilder = null; + if (!types.isEmpty()) { + resultTOBuilder = types.remove(0); + for (GeneratedTOBuilder genTOBuilder : types) { + resultTOBuilder.addEnclosingTransferObject(genTOBuilder); + } + } + + final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value"); + genPropBuilder.setReturnType(Types.primitiveType("char[]", null)); + resultTOBuilder.addEqualsIdentity(genPropBuilder); + resultTOBuilder.addHashIdentity(genPropBuilder); + resultTOBuilder.addToStringProperty(genPropBuilder); + } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilders.add(((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition( - packageName, typeDef, classNameFromLeaf)); + genTOBuilders.add((((TypeProviderImpl) typeProvider)).provideGeneratedTOBuilderForBitsTypeDefinition( + packageName, typeDef, classNameFromLeaf, parentModule.getName())); } if (genTOBuilders != null && !genTOBuilders.isEmpty()) { for (GeneratedTOBuilder genTOBuilder : genTOBuilders) { @@ -1970,9 +1913,9 @@ public final class BindingGeneratorImpl implements BindingGenerator { * Adds the implemented types to type builder. * * The method passes through the list of uses in - * {@code dataNodeContainer}. For every use is obtained coresponding + * {@code dataNodeContainer}. For every use is obtained corresponding * generated type from {@link BindingGeneratorImpl#allGroupings - * allGroupings} which is adde as implements type to + * allGroupings} which is added as implements type to * builder * * @param dataNodeContainer @@ -1986,15 +1929,50 @@ public final class BindingGeneratorImpl implements BindingGenerator { final GeneratedTypeBuilder builder) { for (UsesNode usesNode : dataNodeContainer.getUses()) { if (usesNode.getGroupingPath() != null) { - GeneratedType genType = allGroupings.get(usesNode.getGroupingPath()); + final GeneratedType genType = findGroupingByPath(usesNode.getGroupingPath()).toInstance(); if (genType == null) { throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for " + builder.getName()); } builder.addImplementsType(genType); + builder.addComment(genType.getComment()); } } return builder; } + private GeneratedTypeBuilder findChildNodeByPath(final SchemaPath path) { + for (ModuleContext ctx : genCtx.values()) { + GeneratedTypeBuilder result = ctx.getChildNode(path); + if (result != null) { + return result; + } + } + return null; + } + + private GeneratedTypeBuilder findGroupingByPath(final SchemaPath path) { + for (ModuleContext ctx : genCtx.values()) { + GeneratedTypeBuilder result = ctx.getGrouping(path); + if (result != null) { + return result; + } + } + return null; + } + + private GeneratedTypeBuilder findCaseByPath(final SchemaPath path) { + for (ModuleContext ctx : genCtx.values()) { + GeneratedTypeBuilder result = ctx.getCase(path); + if (result != null) { + return result; + } + } + return null; + } + + public Map getModuleContexts() { + return genCtx; + } + }