2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.sal.binding.generator.impl;
10 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;
11 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
12 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName;
13 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;
14 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.schemaNodeToTransferObjectBuilder;
15 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
16 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.HashMap;
22 import java.util.List;
25 import java.util.concurrent.Future;
27 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
28 import org.opendaylight.yangtools.binding.generator.util.Types;
29 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
30 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
31 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
32 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
33 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
34 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
35 import org.opendaylight.yangtools.sal.binding.model.api.Type;
36 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
37 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
38 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
39 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
40 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder;
41 import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort;
42 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
43 import org.opendaylight.yangtools.yang.binding.DataRoot;
44 import org.opendaylight.yangtools.yang.binding.RpcService;
45 import org.opendaylight.yangtools.yang.common.QName;
46 import org.opendaylight.yangtools.yang.common.RpcResult;
47 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
48 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
49 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
50 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
51 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
52 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
53 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
54 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
55 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
56 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
57 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
58 import org.opendaylight.yangtools.yang.model.api.Module;
59 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
60 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
61 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
62 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
63 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
64 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
65 import org.opendaylight.yangtools.yang.model.api.UsesNode;
66 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
67 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
68 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
69 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
70 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
71 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
72 import org.opendaylight.yangtools.yang.model.util.UnionType;
74 public final class BindingGeneratorImpl implements BindingGenerator {
77 * Outter key represents the package name. Outter value represents map of
78 * all builders in the same package. Inner key represents the schema node
79 * name (in JAVA class/interface name format). Inner value represents
80 * instance of builder for schema node specified in key part.
82 private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
85 * Provide methods for converting YANG types to JAVA types.
87 private TypeProvider typeProvider;
90 * Holds reference to schema context to resolve data of augmented elemnt
91 * when creating augmentation builder
93 private SchemaContext schemaContext;
96 * Each grouping which is converted from schema node to generated type is
97 * added to this map with its Schema path as key to make it easier to get
98 * reference to it. In schema nodes in <code>uses</code> attribute there is
99 * only Schema Path but when building list of implemented interfaces for
100 * Schema node the object of type <code>Type</code> is required. So in this
101 * case is used this map.
103 private final Map<SchemaPath, GeneratedType> allGroupings = new HashMap<SchemaPath, GeneratedType>();
106 * Only parent constructor is invoked.
108 public BindingGeneratorImpl() {
113 * Resolves generated types from <code>context</code> schema nodes of all
116 * Generated types are created for modules, groupings, types, containers,
117 * lists, choices, augments, rpcs, notification, identities.
120 * schema context which contains data about all schema nodes
122 * @return list of types (usually <code>GeneratedType</code>
123 * <code>GeneratedTransferObject</code>which are generated from
124 * <code>context</code> data.
125 * @throws IllegalArgumentException
126 * if param <code>context</code> is null
127 * @throws IllegalStateException
128 * if <code>context</code> contain no modules
131 public List<Type> generateTypes(final SchemaContext context) {
132 if (context == null) {
133 throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
135 if (context.getModules() == null) {
136 throw new IllegalStateException("Schema Context does not contain defined modules!");
139 final List<Type> generatedTypes = new ArrayList<>();
140 schemaContext = context;
141 typeProvider = new TypeProviderImpl(context);
142 final Set<Module> modules = context.getModules();
143 genTypeBuilders = new HashMap<>();
144 for (final Module module : modules) {
146 generatedTypes.addAll(allGroupingsToGenTypes(module));
148 if (false == module.getChildNodes().isEmpty()) {
149 generatedTypes.add(moduleToDataType(module));
151 generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));
152 generatedTypes.addAll(allContainersToGenTypes(module));
153 generatedTypes.addAll(allListsToGenTypes(module));
154 generatedTypes.addAll(allChoicesToGenTypes(module));
155 generatedTypes.addAll(allAugmentsToGenTypes(module));
156 generatedTypes.addAll(allRPCMethodsToGenType(module));
157 generatedTypes.addAll(allNotificationsToGenType(module));
158 generatedTypes.addAll(allIdentitiesToGenTypes(module, context));
161 return generatedTypes;
165 * Resolves generated types from <code>context</code> schema nodes only for
166 * modules specified in <code>modules</code>
168 * Generated types are created for modules, groupings, types, containers,
169 * lists, choices, augments, rpcs, notification, identities.
172 * schema context which contains data about all schema nodes
175 * set of modules for which schema nodes should be generated
177 * @return list of types (usually <code>GeneratedType</code> or
178 * <code>GeneratedTransferObject</code>) which:
180 * <li>are generated from <code>context</code> schema nodes and</li>
181 * <li>are also part of some of the module in <code>modules</code>
184 * @throws IllegalArgumentException
186 * <li>if param <code>context</code> is null or</li>
187 * <li>if param <code>modules</code> is null</li>
189 * @throws IllegalStateException
190 * if <code>context</code> contain no modules
193 public List<Type> generateTypes(final SchemaContext context, final Set<Module> modules) {
194 if (context == null) {
195 throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
197 if (context.getModules() == null) {
198 throw new IllegalStateException("Schema Context does not contain defined modules!");
200 if (modules == null) {
201 throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
204 final List<Type> filteredGenTypes = new ArrayList<>();
205 schemaContext = context;
206 typeProvider = new TypeProviderImpl(context);
207 final Set<Module> contextModules = context.getModules();
208 genTypeBuilders = new HashMap<>();
209 for (final Module contextModule : contextModules) {
210 final List<Type> generatedTypes = new ArrayList<>();
212 generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
213 if (false == contextModule.getChildNodes().isEmpty()) {
214 generatedTypes.add(moduleToDataType(contextModule));
216 generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));
217 generatedTypes.addAll(allContainersToGenTypes(contextModule));
218 generatedTypes.addAll(allListsToGenTypes(contextModule));
219 generatedTypes.addAll(allChoicesToGenTypes(contextModule));
220 generatedTypes.addAll(allAugmentsToGenTypes(contextModule));
221 generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
222 generatedTypes.addAll(allNotificationsToGenType(contextModule));
223 generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));
225 if (modules.contains(contextModule)) {
226 filteredGenTypes.addAll(generatedTypes);
229 return filteredGenTypes;
233 * Converts all extended type definitions of module to the list of
234 * <code>Type</code> objects.
237 * module from which is obtained set of type definitions
238 * @return list of <code>Type</code> which are generated from extended
239 * definition types (object of type <code>ExtendedType</code>)
240 * @throws IllegalArgumentException
242 * <li>if module equals null</li>
243 * <li>if name of module equals null</li>
244 * <li>if type definitions of module equal null</li>
248 private List<Type> allTypeDefinitionsToGenTypes(final Module module) {
249 if (module == null) {
250 throw new IllegalArgumentException("Module reference cannot be NULL!");
252 if (module.getName() == null) {
253 throw new IllegalArgumentException("Module name cannot be NULL!");
255 if (module.getTypeDefinitions() == null) {
256 throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!");
259 final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
260 final List<Type> generatedTypes = new ArrayList<>();
261 for (final TypeDefinition<?> typedef : typeDefinitions) {
262 if (typedef != null) {
263 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef);
264 if ((type != null) && !generatedTypes.contains(type)) {
265 generatedTypes.add(type);
269 return generatedTypes;
273 * Converts all <b>containers</b> of the module to the list of
274 * <code>Type</code> objects.
277 * module from which is obtained DataNodeIterator to iterate over
279 * @return list of <code>Type</code> which are generated from containers
280 * (objects of type <code>ContainerSchemaNode</code>)
281 * @throws IllegalArgumentException
283 * <li>if the module equals null</li>
284 * <li>if the name of module equals null</li>
285 * <li>if the set of child nodes equals null</li>
289 private List<Type> allContainersToGenTypes(final Module module) {
290 if (module == null) {
291 throw new IllegalArgumentException("Module reference cannot be NULL!");
294 if (module.getName() == null) {
295 throw new IllegalArgumentException("Module name cannot be NULL!");
298 if (module.getChildNodes() == null) {
299 throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
300 + " cannot be NULL!");
303 final List<Type> generatedTypes = new ArrayList<>();
304 final DataNodeIterator it = new DataNodeIterator(module);
305 final List<ContainerSchemaNode> schemaContainers = it.allContainers();
306 final String basePackageName = moduleNamespaceToPackageName(module);
307 for (final ContainerSchemaNode container : schemaContainers) {
308 if (!container.isAddedByUses()) {
309 generatedTypes.add(containerToGenType(basePackageName, container));
312 return generatedTypes;
316 * Converts all <b>lists</b> of the module to the list of <code>Type</code>
320 * module from which is obtained DataNodeIterator to iterate over
322 * @return list of <code>Type</code> which are generated from lists (objects
323 * of type <code>ListSchemaNode</code>)
324 * @throws IllegalArgumentException
326 * <li>if the module equals null</li>
327 * <li>if the name of module equals null</li>
328 * <li>if the set of child nodes equals null</li>
332 private List<Type> allListsToGenTypes(final Module module) {
333 if (module == null) {
334 throw new IllegalArgumentException("Module reference cannot be NULL!");
337 if (module.getName() == null) {
338 throw new IllegalArgumentException("Module name cannot be NULL!");
341 if (module.getChildNodes() == null) {
342 throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
343 + " cannot be NULL!");
346 final List<Type> generatedTypes = new ArrayList<>();
347 final DataNodeIterator it = new DataNodeIterator(module);
348 final List<ListSchemaNode> schemaLists = it.allLists();
349 final String basePackageName = moduleNamespaceToPackageName(module);
350 if (schemaLists != null) {
351 for (final ListSchemaNode list : schemaLists) {
352 if (!list.isAddedByUses()) {
353 generatedTypes.addAll(listToGenType(basePackageName, list));
357 return generatedTypes;
361 * Converts all <b>choices</b> of the module to the list of
362 * <code>Type</code> objects.
365 * module from which is obtained DataNodeIterator to iterate over
367 * @return list of <code>Type</code> which are generated from choices
368 * (objects of type <code>ChoiceNode</code>)
369 * @throws IllegalArgumentException
371 * <li>if the module equals null</li>
372 * <li>if the name of module equals null</li> *
376 private List<GeneratedType> allChoicesToGenTypes(final Module module) {
377 if (module == null) {
378 throw new IllegalArgumentException("Module reference cannot be NULL!");
380 if (module.getName() == null) {
381 throw new IllegalArgumentException("Module name cannot be NULL!");
384 final DataNodeIterator it = new DataNodeIterator(module);
385 final List<ChoiceNode> choiceNodes = it.allChoices();
386 final String basePackageName = moduleNamespaceToPackageName(module);
388 final List<GeneratedType> generatedTypes = new ArrayList<>();
389 for (final ChoiceNode choice : choiceNodes) {
390 if ((choice != null) && !choice.isAddedByUses()) {
391 generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice));
394 return generatedTypes;
398 * Converts all <b>augmentation</b> of the module to the list
399 * <code>Type</code> objects.
402 * module from which is obtained list of all augmentation objects
403 * to iterate over them
404 * @return list of <code>Type</code> which are generated from augments
405 * (objects of type <code>AugmentationSchema</code>)
406 * @throws IllegalArgumentException
408 * <li>if the module equals null</li>
409 * <li>if the name of module equals null</li>
410 * <li>if the set of child nodes equals null</li>
414 private List<Type> allAugmentsToGenTypes(final Module module) {
415 if (module == null) {
416 throw new IllegalArgumentException("Module reference cannot be NULL!");
418 if (module.getName() == null) {
419 throw new IllegalArgumentException("Module name cannot be NULL!");
421 if (module.getChildNodes() == null) {
422 throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module "
423 + module.getName() + " cannot be NULL!");
426 final List<Type> generatedTypes = new ArrayList<>();
427 final String basePackageName = moduleNamespaceToPackageName(module);
428 final List<AugmentationSchema> augmentations = resolveAugmentations(module);
429 for (final AugmentationSchema augment : augmentations) {
430 generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment));
432 return generatedTypes;
436 * Returns list of <code>AugmentationSchema</code> objects. The objects are
437 * sorted according to the length of their target path from the shortest to
441 * module from which is obtained list of all augmentation objects
442 * @return list of sorted <code>AugmentationSchema</code> objects obtained
443 * from <code>module</code>
444 * @throws IllegalArgumentException
446 * <li>if the module equals null</li>
447 * <li>if the set of augmentation equals null</li>
451 private List<AugmentationSchema> resolveAugmentations(final Module module) {
452 if (module == null) {
453 throw new IllegalArgumentException("Module reference cannot be NULL!");
455 if (module.getAugmentations() == null) {
456 throw new IllegalStateException("Augmentations Set cannot be NULL!");
459 final Set<AugmentationSchema> augmentations = module.getAugmentations();
460 final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);
461 Collections.sort(sortedAugmentations, new Comparator<AugmentationSchema>() {
464 public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) {
466 if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) {
468 } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) {
476 return sortedAugmentations;
480 * Converts whole <b>module</b> to <code>GeneratedType</code> object.
481 * Firstly is created the module builder object from which is finally
482 * obtained reference to <code>GeneratedType</code> object.
485 * module from which are obtained the module name, child nodes,
486 * uses and is derived package name
487 * @return <code>GeneratedType</code> which is internal representation of
489 * @throws IllegalArgumentException
490 * if the module equals null
493 private GeneratedType moduleToDataType(final Module module) {
494 if (module == null) {
495 throw new IllegalArgumentException("Module reference cannot be NULL!");
498 final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
499 addImplementedInterfaceFromUses(module, moduleDataTypeBuilder);
500 moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class));
502 final String basePackageName = moduleNamespaceToPackageName(module);
503 if (moduleDataTypeBuilder != null) {
504 final Set<DataSchemaNode> dataNodes = module.getChildNodes();
505 resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes);
507 return moduleDataTypeBuilder.toInstance();
511 * Converts all <b>rpcs</b> inputs and outputs substatements of the module
512 * to the list of <code>Type</code> objects. In addition are to containers
513 * and lists which belong to input or output also part of returning list.
516 * module from which is obtained set of all rpc objects to
518 * @return list of <code>Type</code> which are generated from rpcs inputs,
519 * outputs + container and lists which are part of inputs or outputs
520 * @throws IllegalArgumentException
522 * <li>if the module equals null</li>
523 * <li>if the name of module equals null</li>
524 * <li>if the set of child nodes equals null</li>
528 private List<Type> allRPCMethodsToGenType(final Module module) {
529 if (module == null) {
530 throw new IllegalArgumentException("Module reference cannot be NULL!");
533 if (module.getName() == null) {
534 throw new IllegalArgumentException("Module name cannot be NULL!");
537 if (module.getChildNodes() == null) {
538 throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module "
539 + module.getName() + " cannot be NULL!");
542 final String basePackageName = moduleNamespaceToPackageName(module);
543 final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
545 if (rpcDefinitions.isEmpty()) {
546 return Collections.emptyList();
549 final List<Type> genRPCTypes = new ArrayList<>();
550 final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service");
551 interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class));
552 final Type future = Types.typeForClass(Future.class);
553 for (final RpcDefinition rpc : rpcDefinitions) {
556 String rpcName = parseToClassName(rpc.getQName().getLocalName());
557 String rpcMethodName = parseToValidParamName(rpcName);
558 MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName);
560 final List<DataNodeIterator> rpcInOut = new ArrayList<>();
562 ContainerSchemaNode input = rpc.getInput();
563 ContainerSchemaNode output = rpc.getOutput();
566 rpcInOut.add(new DataNodeIterator(input));
567 GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
568 addImplementedInterfaceFromUses(input, inType);
569 inType.addImplementsType(Types.DATA_OBJECT);
570 resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());
571 Type inTypeInstance = inType.toInstance();
572 genRPCTypes.add(inTypeInstance);
573 method.addParameter(inTypeInstance, "input");
576 Type outTypeInstance = Types.typeForClass(Void.class);
577 if (output != null) {
578 rpcInOut.add(new DataNodeIterator(output));
579 GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
580 addImplementedInterfaceFromUses(output, outType);
581 outType.addImplementsType(Types.DATA_OBJECT);
582 resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());
583 outTypeInstance = outType.toInstance();
584 genRPCTypes.add(outTypeInstance);
588 final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance);
589 method.setReturnType(Types.parameterizedTypeFor(future, rpcRes));
590 for (DataNodeIterator it : rpcInOut) {
591 List<ContainerSchemaNode> nContainers = it.allContainers();
592 if ((nContainers != null) && !nContainers.isEmpty()) {
593 for (final ContainerSchemaNode container : nContainers) {
594 if (!container.isAddedByUses()) {
595 genRPCTypes.add(containerToGenType(basePackageName, container));
599 List<ListSchemaNode> nLists = it.allLists();
600 if ((nLists != null) && !nLists.isEmpty()) {
601 for (final ListSchemaNode list : nLists) {
602 if (!list.isAddedByUses()) {
603 genRPCTypes.addAll(listToGenType(basePackageName, list));
610 genRPCTypes.add(interfaceBuilder.toInstance());
615 * Converts all <b>notifications</b> of the module to the list of
616 * <code>Type</code> objects. In addition are to this list added containers
617 * and lists which are part of this notification.
620 * module from which is obtained set of all notification objects
621 * to iterate over them
622 * @return list of <code>Type</code> which are generated from notification
623 * (object of type <code>NotificationDefinition</code>
624 * @throws IllegalArgumentException
626 * <li>if the module equals null</li>
627 * <li>if the name of module equals null</li>
628 * <li>if the set of child nodes equals null</li>
632 private List<Type> allNotificationsToGenType(final Module module) {
633 if (module == null) {
634 throw new IllegalArgumentException("Module reference cannot be NULL!");
637 if (module.getName() == null) {
638 throw new IllegalArgumentException("Module name cannot be NULL!");
641 if (module.getChildNodes() == null) {
642 throw new IllegalArgumentException("Reference to Set of Notification Definitions in module "
643 + module.getName() + " cannot be NULL!");
646 final String basePackageName = moduleNamespaceToPackageName(module);
647 final List<Type> genNotifyTypes = new ArrayList<>();
648 final Set<NotificationDefinition> notifications = module.getNotifications();
650 for (final NotificationDefinition notification : notifications) {
651 if (notification != null) {
652 DataNodeIterator it = new DataNodeIterator(notification);
655 for (ContainerSchemaNode node : it.allContainers()) {
656 if (!node.isAddedByUses()) {
657 genNotifyTypes.add(containerToGenType(basePackageName, node));
661 for (ListSchemaNode node : it.allLists()) {
662 if (!node.isAddedByUses()) {
663 genNotifyTypes.addAll(listToGenType(basePackageName, node));
666 final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName,
668 notificationTypeBuilder.addImplementsType(Types
669 .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class));
670 // Notification object
671 resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes());
672 genNotifyTypes.add(notificationTypeBuilder.toInstance());
675 return genNotifyTypes;
679 * Converts all <b>identities</b> of the module to the list of
680 * <code>Type</code> objects.
683 * module from which is obtained set of all identity objects to
686 * schema context only used as input parameter for method
687 * {@link identityToGenType}
688 * @return list of <code>Type</code> which are generated from identities
689 * (object of type <code>IdentitySchemaNode</code>
692 private List<Type> allIdentitiesToGenTypes(final Module module, final SchemaContext context) {
693 List<Type> genTypes = new ArrayList<>();
695 final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
697 final String basePackageName = moduleNamespaceToPackageName(module);
699 if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
700 for (final IdentitySchemaNode identity : schemaIdentities) {
701 genTypes.add(identityToGenType(basePackageName, identity, context));
708 * Converts the <b>identity</b> object to GeneratedType. Firstly it is
709 * created transport object builder. If identity contains base identity then
710 * reference to base identity is added to superior identity as its extend.
711 * If identity doesn't contain base identity then only reference to abstract
712 * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity
713 * BaseIdentity} is added
715 * @param basePackageName
716 * string containing package name to which identity belongs
718 * IdentitySchemaNode which contains data about identity
720 * SchemaContext which is used to get package and name
721 * information about base of identity
723 * @return GeneratedType which is generated from identity (object of type
724 * <code>IdentitySchemaNode</code>
727 private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity,
728 final SchemaContext context) {
729 if (identity == null) {
733 final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
734 final String genTypeName = parseToClassName(identity.getQName().getLocalName());
735 final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
737 IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
738 if (baseIdentity != null) {
739 Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
741 final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
742 final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName());
744 GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
745 newType.setExtendsType(gto);
747 newType.setExtendsType(Types.getBaseIdentityTO());
749 newType.setAbstract(true);
750 return newType.toInstance();
754 * Converts all <b>groupings</b> of the module to the list of
755 * <code>Type</code> objects. Firstly are groupings sorted according mutual
756 * dependencies. At least dependend (indepedent) groupings are in the list
757 * saved at first positions. For every grouping the record is added to map
758 * {@link BindingGeneratorImpl#allGroupings allGroupings}
761 * module from which is obtained set of all grouping objects to
763 * @return list of <code>Type</code> which are generated from groupings
764 * (object of type <code>GroupingDefinition</code>)
767 private List<Type> allGroupingsToGenTypes(final Module module) {
768 if (module == null) {
769 throw new IllegalArgumentException("Module parameter can not be null");
771 final List<Type> genTypes = new ArrayList<>();
772 final String basePackageName = moduleNamespaceToPackageName(module);
773 final Set<GroupingDefinition> groupings = module.getGroupings();
774 List<GroupingDefinition> groupingsSortedByDependencies;
776 groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings);
778 for (final GroupingDefinition grouping : groupingsSortedByDependencies) {
779 GeneratedType genType = groupingToGenType(basePackageName, grouping);
780 genTypes.add(genType);
781 SchemaPath schemaPath = grouping.getPath();
782 allGroupings.put(schemaPath, genType);
788 * Converts individual grouping to GeneratedType. Firstly generated type
789 * builder is created and every child node of grouping is resolved to the
792 * @param basePackageName
793 * string containing name of package to which grouping belongs.
795 * GroupingDefinition which contains data about grouping
796 * @return GeneratedType which is generated from grouping (object of type
797 * <code>GroupingDefinition</code>)
799 private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) {
800 if (grouping == null) {
804 final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath());
805 final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();
806 final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping);
808 resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
809 return typeBuilder.toInstance();
813 * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base
814 * type of <code>typeDefinition</code> is of the type ExtendedType then this
815 * method is recursivelly called with this base type.
817 * @param typeDefinition
818 * TypeDefinition in which should be EnumTypeDefinition found as
820 * @return EnumTypeDefinition if it is found inside
821 * <code>typeDefinition</code> or <code>null</code> in other case
823 private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition<?> typeDefinition) {
824 if (typeDefinition != null) {
825 if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
826 return (EnumTypeDefinition) typeDefinition.getBaseType();
827 } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
828 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
835 * Adds enumeration builder created from <code>enumTypeDef</code> to
836 * <code>typeBuilder</code>.
838 * Each <code>enumTypeDef</code> item is added to builder with its name and
842 * EnumTypeDefinition contains enum data
844 * string contains name which will be assigned to enumeration
847 * GeneratedTypeBuilder to which will be enum builder assigned
848 * @return enumeration builder which contais data from
849 * <code>enumTypeDef</code>
851 private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
852 final GeneratedTypeBuilder typeBuilder) {
853 if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)
854 && (enumTypeDef.getQName().getLocalName() != null)) {
856 final String enumerationName = parseToClassName(enumName);
857 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
859 if (enumBuilder != null) {
860 final List<EnumPair> enums = enumTypeDef.getValues();
863 for (final EnumPair enumPair : enums) {
864 if (enumPair != null) {
865 final String enumPairName = parseToClassName(enumPair.getName());
866 Integer enumPairValue = enumPair.getValue();
868 if (enumPairValue == null) {
869 enumPairValue = listIndex;
871 enumBuilder.addValue(enumPairName, enumPairValue);
883 * Generates type builder for <code>module</code>.
886 * Module which is source of package name for generated type
889 * string which is added to the module class name representation
891 * @return instance of GeneratedTypeBuilder which represents
892 * <code>module</code>.
893 * @throws IllegalArgumentException
894 * if <code>module</code> equals null
896 private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) {
897 if (module == null) {
898 throw new IllegalArgumentException("Module reference cannot be NULL!");
900 String packageName = moduleNamespaceToPackageName(module);
901 final String moduleName = parseToClassName(module.getName()) + postfix;
903 return new GeneratedTypeBuilderImpl(packageName, moduleName);
908 * Converts <code>augSchema</code> to list of <code>Type</code> which
909 * contains generated type for augmentation. In addition there are also
910 * generated types for all containers, list and choices which are child of
911 * <code>augSchema</code> node or a generated types for cases are added if
912 * augmented node is choice.
914 * @param augmentPackageName
915 * string with the name of the package to which the augmentation
918 * AugmentationSchema which is contains data about agumentation
919 * (target path, childs...)
920 * @return list of <code>Type</code> objects which contains generated type
921 * for augmentation and for container, list and choice child nodes
922 * @throws IllegalArgumentException
924 * <li>if <code>augmentPackageName</code> equals null</li>
925 * <li>if <code>augSchema</code> equals null</li>
926 * <li>if target path of <code>augSchema</code> equals null</li>
929 private List<Type> augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) {
930 if (augmentPackageName == null) {
931 throw new IllegalArgumentException("Package Name cannot be NULL!");
933 if (augSchema == null) {
934 throw new IllegalArgumentException("Augmentation Schema cannot be NULL!");
936 if (augSchema.getTargetPath() == null) {
937 throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL).");
940 final List<Type> genTypes = new ArrayList<>();
942 // EVERY augmented interface will extends Augmentation<T> interface
943 // and DataObject interface!!!
944 final SchemaPath targetPath = augSchema.getTargetPath();
945 final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
946 if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
947 && (targetSchemaNode.getQName().getLocalName() != null)) {
948 final Module targetModule = findParentModule(schemaContext, targetSchemaNode);
949 final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
950 final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());
951 final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();
952 final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
954 if (!(targetSchemaNode instanceof ChoiceNode)) {
955 final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
956 targetPackageName, targetSchemaNodeName, augSchema);
957 final GeneratedType augType = augTypeBuilder.toInstance();
958 genTypes.add(augType);
960 final Type refChoiceType = new ReferencedTypeImpl(targetPackageName,
961 parseToClassName(targetSchemaNodeName));
962 final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode;
963 final Set<ChoiceCaseNode> choiceCaseNodes = choiceTarget.getCases();
964 genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType,
967 genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));
973 * Returns a generated type builder for an augmentation.
975 * The name of the type builder is equal to the name of augmented node with
976 * serial number as suffix.
978 * @param augmentPackageName
979 * string with contains the package name to which the augment
981 * @param targetPackageName
982 * string with the package name to which the augmented node
984 * @param targetSchemaNodeName
985 * string with the name of the augmented node
987 * augmentation schema which contains data about the child nodes
988 * and uses of augment
989 * @return generated type builder for augment
991 private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName,
992 final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) {
993 final String targetTypeName = parseToClassName(targetSchemaNodeName);
994 Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
995 if (augmentBuilders == null) {
996 augmentBuilders = new HashMap<>();
997 genTypeBuilders.put(augmentPackageName, augmentBuilders);
1000 final String augTypeName = augGenTypeName(augmentBuilders, targetTypeName);
1001 final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName);
1002 final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
1004 final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
1006 augTypeBuilder.addImplementsType(Types.DATA_OBJECT);
1007 augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
1008 addImplementedInterfaceFromUses(augSchema, augTypeBuilder);
1010 augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes);
1011 augmentBuilders.put(augTypeName, augTypeBuilder);
1012 return augTypeBuilder;
1016 * Convert a container, list and choice subnodes (and recursivelly their
1017 * subnodes) of augment to generated types
1019 * @param augBasePackageName
1020 * string with the augment package name
1021 * @param augChildNodes
1022 * set of data schema nodes which represents child nodes of the
1025 * @return list of <code>Type</code> which represents container, list and
1026 * choice subnodes of augment
1028 private List<Type> augmentationBodyToGenTypes(final String augBasePackageName,
1029 final Set<DataSchemaNode> augChildNodes) {
1030 final List<Type> genTypes = new ArrayList<>();
1031 final List<DataNodeIterator> augSchemaIts = new ArrayList<>();
1032 for (final DataSchemaNode childNode : augChildNodes) {
1033 if (childNode instanceof DataNodeContainer) {
1034 augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode));
1036 if (childNode instanceof ContainerSchemaNode) {
1037 genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode));
1038 } else if (childNode instanceof ListSchemaNode) {
1039 genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));
1041 } else if (childNode instanceof ChoiceNode) {
1042 final ChoiceNode choice = (ChoiceNode) childNode;
1043 for (final ChoiceCaseNode caseNode : choice.getCases()) {
1044 augSchemaIts.add(new DataNodeIterator(caseNode));
1046 genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode));
1050 for (final DataNodeIterator it : augSchemaIts) {
1051 final List<ContainerSchemaNode> augContainers = it.allContainers();
1052 final List<ListSchemaNode> augLists = it.allLists();
1053 final List<ChoiceNode> augChoices = it.allChoices();
1055 if (augContainers != null) {
1056 for (final ContainerSchemaNode container : augContainers) {
1057 genTypes.add(containerToGenType(augBasePackageName, container));
1060 if (augLists != null) {
1061 for (final ListSchemaNode list : augLists) {
1062 genTypes.addAll(listToGenType(augBasePackageName, list));
1065 if (augChoices != null) {
1066 for (final ChoiceNode choice : augChoices) {
1067 genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice));
1075 * Returns first unique name for the augment generated type builder. The
1076 * generated type builder name for augment consists from name of augmented
1077 * node and serial number of its augmentation.
1080 * map of builders which were created in the package to which the
1081 * augmentation belongs
1082 * @param genTypeName
1083 * string with name of augmented node
1084 * @return string with unique name for augmentation builder
1086 private String augGenTypeName(final Map<String, GeneratedTypeBuilder> builders, final String genTypeName) {
1087 String augTypeName = genTypeName;
1090 while ((builders != null) && builders.containsKey(genTypeName + index)) {
1093 augTypeName += index;
1098 * Converts <code>containerNode</code> to generated type. Firstly the
1099 * generated type builder is created. The subnodes of
1100 * <code>containerNode</code> are added as methods and the instance of
1101 * <code>GeneratedType</code> is returned.
1103 * @param basePackageName
1104 * string with name of the package to which the superior node
1106 * @param containerNode
1107 * container schema node with the data about childs nodes and
1109 * @return generated type for <code>containerNode</code>
1111 private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) {
1112 if (containerNode == null) {
1116 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
1117 final Set<DataSchemaNode> schemaNodes = containerNode.getChildNodes();
1118 final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode);
1120 resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
1121 return typeBuilder.toInstance();
1126 * @param basePackageName
1127 * @param typeBuilder
1128 * @param schemaNodes
1131 private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName,
1132 final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
1133 if ((schemaNodes != null) && (typeBuilder != null)) {
1134 for (final DataSchemaNode schemaNode : schemaNodes) {
1135 if (schemaNode.isAugmenting() || schemaNode.isAddedByUses()) {
1138 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
1144 private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName,
1145 final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
1146 if ((schemaNodes != null) && (typeBuilder != null)) {
1147 for (final DataSchemaNode schemaNode : schemaNodes) {
1148 if (schemaNode.isAugmenting()) {
1149 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
1156 private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode,
1157 final GeneratedTypeBuilder typeBuilder) {
1158 if (schemaNode != null && typeBuilder != null) {
1159 if (schemaNode instanceof LeafSchemaNode) {
1160 resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode);
1161 } else if (schemaNode instanceof LeafListSchemaNode) {
1162 resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
1163 } else if (schemaNode instanceof ContainerSchemaNode) {
1164 resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
1165 } else if (schemaNode instanceof ListSchemaNode) {
1166 resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
1167 } else if (schemaNode instanceof ChoiceNode) {
1168 resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode);
1173 private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
1174 final ChoiceNode choiceNode) {
1175 if (basePackageName == null) {
1176 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
1178 if (typeBuilder == null) {
1179 throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1181 if (choiceNode == null) {
1182 throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
1185 final String choiceName = choiceNode.getQName().getLocalName();
1186 if (choiceName != null && !choiceNode.isAddedByUses()) {
1187 final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
1188 final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);
1189 constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType);
1193 private List<GeneratedType> choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) {
1194 if (basePackageName == null) {
1195 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
1197 if (choiceNode == null) {
1198 throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
1201 final List<GeneratedType> generatedTypes = new ArrayList<>();
1202 final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
1203 final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
1204 choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT);
1205 final GeneratedType choiceType = choiceTypeBuilder.toInstance();
1207 generatedTypes.add(choiceType);
1208 final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();
1209 if ((caseNodes != null) && !caseNodes.isEmpty()) {
1210 generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes));
1212 return generatedTypes;
1215 private List<GeneratedType> generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType,
1216 final Set<ChoiceCaseNode> caseNodes) {
1217 if (basePackageName == null) {
1218 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
1220 if (refChoiceType == null) {
1221 throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
1223 if (caseNodes == null) {
1224 throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
1227 final List<GeneratedType> generatedTypes = new ArrayList<>();
1228 for (final ChoiceCaseNode caseNode : caseNodes) {
1229 if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) {
1230 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
1231 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
1232 caseTypeBuilder.addImplementsType(refChoiceType);
1234 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
1235 if (childNodes != null) {
1236 resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
1238 generatedTypes.add(caseTypeBuilder.toInstance());
1242 return generatedTypes;
1246 * Generates list of generated types for all the cases of a choice which are
1247 * added to the choice through the augment.
1250 * @param basePackageName
1251 * string contains name of package to which augment belongs. If
1252 * an augmented choice is from an other package (pcg1) than an
1253 * augmenting choice (pcg2) then case's of the augmenting choice
1254 * will belong to pcg2.
1255 * @param refChoiceType
1256 * Type which represents the choice to which case belongs. Every
1257 * case has to contain its choice in extend part.
1259 * set of choice case nodes for which is checked if are/aren't
1260 * added to choice through augmentation
1261 * @return list of generated types which represents augmented cases of
1262 * choice <code>refChoiceType</code>
1263 * @throws IllegalArgumentException
1265 * <li>if <code>basePackageName</code> equals null</li>
1266 * <li>if <code>refChoiceType</code> equals null</li>
1267 * <li>if <code>caseNodes</code> equals null</li>
1270 private List<GeneratedType> generateTypesFromAugmentedChoiceCases(final String basePackageName,
1271 final Type refChoiceType, final Set<ChoiceCaseNode> caseNodes) {
1272 if (basePackageName == null) {
1273 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
1275 if (refChoiceType == null) {
1276 throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
1278 if (caseNodes == null) {
1279 throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
1282 final List<GeneratedType> generatedTypes = new ArrayList<>();
1283 for (final ChoiceCaseNode caseNode : caseNodes) {
1284 if (caseNode != null && caseNode.isAugmenting()) {
1285 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
1286 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
1287 caseTypeBuilder.addImplementsType(refChoiceType);
1289 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
1290 if (childNodes != null) {
1291 resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
1293 generatedTypes.add(caseTypeBuilder.toInstance());
1297 return generatedTypes;
1300 private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
1301 if ((leaf != null) && (typeBuilder != null)) {
1302 final String leafName = leaf.getQName().getLocalName();
1303 String leafDesc = leaf.getDescription();
1304 if (leafDesc == null) {
1308 if (leafName != null && !leaf.isAddedByUses()) {
1309 final TypeDefinition<?> typeDef = leaf.getType();
1311 Type returnType = null;
1312 if (typeDef instanceof EnumTypeDefinition) {
1313 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
1314 final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
1315 final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName,
1318 if (enumBuilder != null) {
1319 returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
1321 ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
1322 } else if (typeDef instanceof UnionType) {
1323 GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
1324 if (genTOBuilder != null) {
1325 returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
1327 } else if (typeDef instanceof BitsTypeDefinition) {
1328 GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
1329 if (genTOBuilder != null) {
1330 returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
1333 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
1335 if (returnType != null) {
1336 constructGetter(typeBuilder, leafName, leafDesc, returnType);
1344 private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
1345 boolean isReadOnly) {
1346 if ((leaf != null) && (toBuilder != null)) {
1347 final String leafName = leaf.getQName().getLocalName();
1348 String leafDesc = leaf.getDescription();
1349 if (leafDesc == null) {
1353 if (leafName != null && !leaf.isAddedByUses()) {
1354 final TypeDefinition<?> typeDef = leaf.getType();
1356 // TODO: properly resolve enum types
1357 final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
1359 if (returnType != null) {
1360 final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName));
1362 propBuilder.setReadOnly(isReadOnly);
1363 propBuilder.setReturnType(returnType);
1364 propBuilder.setComment(leafDesc);
1366 toBuilder.addEqualsIdentity(propBuilder);
1367 toBuilder.addHashIdentity(propBuilder);
1368 toBuilder.addToStringProperty(propBuilder);
1377 private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {
1378 if ((node != null) && (typeBuilder != null)) {
1379 final String nodeName = node.getQName().getLocalName();
1380 String nodeDesc = node.getDescription();
1381 if (nodeDesc == null) {
1385 if (nodeName != null && !node.isAddedByUses()) {
1386 final TypeDefinition<?> type = node.getType();
1387 final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type));
1389 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
1396 private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
1397 final ContainerSchemaNode containerNode) {
1398 if ((containerNode != null) && (typeBuilder != null)) {
1399 final String nodeName = containerNode.getQName().getLocalName();
1401 if (nodeName != null && !containerNode.isAddedByUses()) {
1402 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
1404 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);
1405 constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType);
1413 private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
1414 final ListSchemaNode schemaNode) {
1415 if ((schemaNode != null) && (typeBuilder != null)) {
1416 final String listName = schemaNode.getQName().getLocalName();
1418 if (listName != null && !schemaNode.isAddedByUses()) {
1419 final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());
1420 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);
1421 constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
1429 * Method instantiates new Generated Type Builder and sets the implements
1430 * definitions of Data Object and Augmentable.
1432 * @param packageName
1433 * Generated Type Package Name
1435 * Schema Node definition
1436 * @return Generated Type Builder instance for Schema Node definition
1438 private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
1439 final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");
1440 builder.addImplementsType(Types.DATA_OBJECT);
1441 if (!(schemaNode instanceof GroupingDefinition)) {
1442 builder.addImplementsType(Types.augmentableTypeFor(builder));
1445 if (schemaNode instanceof DataNodeContainer) {
1446 addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder);
1454 * @param packageName
1458 private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
1459 return addRawInterfaceDefinition(packageName, schemaNode, "");
1462 private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,
1463 final String prefix) {
1464 if (schemaNode == null) {
1465 throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
1467 if (packageName == null) {
1468 throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1470 if (schemaNode.getQName() == null) {
1471 throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!");
1473 final String schemaNodeName = schemaNode.getQName().getLocalName();
1474 if (schemaNodeName == null) {
1475 throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!");
1478 final String genTypeName;
1479 if (prefix == null) {
1480 genTypeName = parseToClassName(schemaNodeName);
1482 genTypeName = prefix + parseToClassName(schemaNodeName);
1485 final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
1486 if (!genTypeBuilders.containsKey(packageName)) {
1487 final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
1488 builders.put(genTypeName, newType);
1489 genTypeBuilders.put(packageName, builders);
1491 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
1492 if (!builders.containsKey(genTypeName)) {
1493 builders.put(genTypeName, newType);
1499 private String getterMethodName(final String methodName) {
1500 final StringBuilder method = new StringBuilder();
1501 method.append("get");
1502 method.append(parseToClassName(methodName));
1503 return method.toString();
1506 private String setterMethodName(final String methodName) {
1507 final StringBuilder method = new StringBuilder();
1508 method.append("set");
1509 method.append(parseToClassName(methodName));
1510 return method.toString();
1513 private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,
1514 final String schemaNodeName, final String comment, final Type returnType) {
1515 final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName));
1517 getMethod.setComment(comment);
1518 getMethod.setReturnType(returnType);
1523 private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder,
1524 final String schemaNodeName, final String comment, final Type parameterType) {
1525 final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName));
1527 setMethod.setComment(comment);
1528 setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName));
1529 setMethod.setReturnType(Types.voidType());
1534 private List<Type> listToGenType(final String basePackageName, final ListSchemaNode list) {
1535 if (basePackageName == null) {
1536 throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1539 throw new IllegalArgumentException("List Schema Node cannot be NULL!");
1542 final String packageName = packageNameForGeneratedType(basePackageName, list.getPath());
1543 final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list);
1544 final List<String> listKeys = listKeys(list);
1545 GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys);
1547 final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
1549 for (final DataSchemaNode schemaNode : schemaNodes) {
1550 if (schemaNode.isAugmenting()) {
1553 addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys);
1555 return typeBuildersToGenTypes(typeBuilder, genTOBuilder);
1558 private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode,
1559 final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
1560 if (schemaNode == null) {
1561 throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
1564 if (typeBuilder == null) {
1565 throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1568 if (schemaNode instanceof LeafSchemaNode) {
1569 final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
1570 if (!isPartOfListKey(leaf, listKeys)) {
1571 resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
1573 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
1575 } else if (schemaNode instanceof LeafListSchemaNode) {
1576 resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
1577 } else if (schemaNode instanceof ContainerSchemaNode) {
1578 resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
1579 } else if (schemaNode instanceof ListSchemaNode) {
1580 resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
1584 private List<Type> typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {
1585 final List<Type> genTypes = new ArrayList<>();
1586 if (typeBuilder == null) {
1587 throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1590 if (genTOBuilder != null) {
1591 final GeneratedTransferObject genTO = genTOBuilder.toInstance();
1592 constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO);
1593 genTypes.add(genTO);
1595 genTypes.add(typeBuilder.toInstance());
1603 private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) {
1604 final String listName = list.getQName().getLocalName() + "Key";
1605 return schemaNodeToTransferObjectBuilder(packageName, list, listName);
1608 private boolean isPartOfListKey(final LeafSchemaNode leaf, final List<String> keys) {
1609 if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
1610 final String leafName = leaf.getQName().getLocalName();
1611 if (keys.contains(leafName)) {
1618 private List<String> listKeys(final ListSchemaNode list) {
1619 final List<String> listKeys = new ArrayList<>();
1621 if (list.getKeyDefinition() != null) {
1622 final List<QName> keyDefinitions = list.getKeyDefinition();
1624 for (final QName keyDefinition : keyDefinitions) {
1625 listKeys.add(keyDefinition.getLocalName());
1631 private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) {
1632 if (packageName == null) {
1633 throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1636 throw new IllegalArgumentException("List Schema Node cannot be NULL!");
1639 final String schemaNodeName = list.getQName().getLocalName();
1640 final String genTypeName = parseToClassName(schemaNodeName);
1642 GeneratedTypeBuilder typeBuilder = null;
1643 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
1644 if (builders != null) {
1645 typeBuilder = builders.get(genTypeName);
1647 if (typeBuilder == null) {
1648 typeBuilder = addDefaultInterfaceDefinition(packageName, list);
1653 private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list,
1654 final List<String> listKeys) {
1655 GeneratedTOBuilder genTOBuilder = null;
1656 if (listKeys.size() > 0) {
1657 genTOBuilder = resolveListKey(packageName, list);
1659 return genTOBuilder;
1662 private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
1664 String className = parseToClassName(leafName);
1665 GeneratedTOBuilder genTOBuilder = null;
1666 if (typeDef instanceof UnionType) {
1667 genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition(
1668 typeBuilder.getFullyQualifiedName(), typeDef, className);
1669 } else if (typeDef instanceof BitsTypeDefinition) {
1670 genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(
1671 typeBuilder.getFullyQualifiedName(), typeDef, className);
1673 if (genTOBuilder != null) {
1674 typeBuilder.addEnclosingTransferObject(genTOBuilder);
1675 return genTOBuilder;
1682 * Adds the implemented types to type builder. The method passes through the
1683 * list of elements which contains {@code dataNodeContainer} and adds them
1684 * as <i>implements type</i> to <code>builder</code>
1686 * @param dataNodeContainer
1687 * element which contains the list of used YANG groupings
1689 * builder to which are added implemented types according to
1690 * <code>dataNodeContainer</code>
1691 * @return generated type builder which contains implemented types
1693 private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer,
1694 final GeneratedTypeBuilder builder) {
1695 for (UsesNode usesNode : dataNodeContainer.getUses()) {
1696 if (usesNode.getGroupingPath() != null) {
1697 GeneratedType genType = allGroupings.get(usesNode.getGroupingPath());
1698 if (genType == null) {
1699 throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for "
1700 + builder.getName());
1702 builder.addImplementsType(genType);