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.controller.sal.binding.generator.impl;
10 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
11 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
12 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
15 import java.util.concurrent.Future;
17 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
18 import org.opendaylight.controller.binding.generator.util.Types;
19 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
20 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
21 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
22 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
23 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
24 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
25 import org.opendaylight.controller.sal.binding.model.api.Type;
26 import org.opendaylight.controller.sal.binding.model.api.type.builder.*;
27 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
28 import org.opendaylight.controller.yang.binding.Notification;
29 import org.opendaylight.controller.yang.common.QName;
30 import org.opendaylight.controller.yang.common.RpcResult;
31 import org.opendaylight.controller.yang.model.api.*;
32 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
33 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
34 import org.opendaylight.controller.yang.model.util.DataNodeIterator;
35 import org.opendaylight.controller.yang.model.util.ExtendedType;
36 import org.opendaylight.controller.yang.model.util.SchemaContextUtil;
38 public final class BindingGeneratorImpl implements BindingGenerator {
40 private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
41 private TypeProvider typeProvider;
42 private SchemaContext schemaContext;
44 public BindingGeneratorImpl() {
49 public List<Type> generateTypes(final SchemaContext context) {
50 if (context == null) {
51 throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
53 if (context.getModules() == null) {
54 throw new IllegalStateException("Schema Context does not contain defined modules!");
57 final List<Type> generatedTypes = new ArrayList<>();
58 schemaContext = context;
59 typeProvider = new TypeProviderImpl(context);
60 final Set<Module> modules = context.getModules();
61 genTypeBuilders = new HashMap<>();
62 for (final Module module : modules) {
63 generatedTypes.add(moduleToDataType(module));
64 generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));
65 generatedTypes.addAll(allContainersToGenTypes(module));
66 generatedTypes.addAll(allListsToGenTypes(module));
67 generatedTypes.addAll(allChoicesToGenTypes(module));
68 generatedTypes.addAll(allAugmentsToGenTypes(module));
69 generatedTypes.addAll(allRPCMethodsToGenType(module));
70 generatedTypes.addAll(allNotificationsToGenType(module));
71 generatedTypes.addAll(allIdentitiesToGenTypes(module, context));
72 generatedTypes.addAll(allGroupingsToGenTypes(module));
74 return generatedTypes;
78 public List<Type> generateTypes(final SchemaContext context, final Set<Module> modules) {
79 if (context == null) {
80 throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
82 if (context.getModules() == null) {
83 throw new IllegalStateException("Schema Context does not contain defined modules!");
85 if (modules == null) {
86 throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
89 final List<Type> filteredGenTypes = new ArrayList<>();
90 schemaContext = context;
91 typeProvider = new TypeProviderImpl(context);
92 final Set<Module> contextModules = context.getModules();
93 genTypeBuilders = new HashMap<>();
94 for (final Module contextModule : contextModules) {
95 final List<Type> generatedTypes = new ArrayList<>();
97 generatedTypes.add(moduleToDataType(contextModule));
98 generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));
99 generatedTypes.addAll(allContainersToGenTypes(contextModule));
100 generatedTypes.addAll(allListsToGenTypes(contextModule));
101 generatedTypes.addAll(allChoicesToGenTypes(contextModule));
102 generatedTypes.addAll(allAugmentsToGenTypes(contextModule));
103 generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
104 generatedTypes.addAll(allNotificationsToGenType(contextModule));
105 generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));
106 generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
108 if (modules.contains(contextModule)) {
109 filteredGenTypes.addAll(generatedTypes);
112 return filteredGenTypes;
115 private List<Type> allTypeDefinitionsToGenTypes(final Module module) {
116 if (module == null) {
117 throw new IllegalArgumentException("Module reference cannot be NULL!");
119 if (module.getName() == null) {
120 throw new IllegalArgumentException("Module name cannot be NULL!");
122 if (module.getTypeDefinitions() == null) {
123 throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!");
126 final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
127 final List<Type> generatedTypes = new ArrayList<>();
128 for (final TypeDefinition<?> typedef : typeDefinitions) {
129 if (typedef != null) {
130 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef);
131 if ((type != null) && !generatedTypes.contains(type)) {
132 generatedTypes.add(type);
136 return generatedTypes;
139 private List<Type> allContainersToGenTypes(final Module module) {
140 if (module == null) {
141 throw new IllegalArgumentException("Module reference cannot be NULL!");
144 if (module.getName() == null) {
145 throw new IllegalArgumentException("Module name cannot be NULL!");
148 if (module.getChildNodes() == null) {
149 throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
150 + " cannot be NULL!");
153 final List<Type> generatedTypes = new ArrayList<>();
154 final DataNodeIterator it = new DataNodeIterator(module);
155 final List<ContainerSchemaNode> schemaContainers = it.allContainers();
156 final String basePackageName = moduleNamespaceToPackageName(module);
157 for (final ContainerSchemaNode container : schemaContainers) {
158 generatedTypes.add(containerToGenType(basePackageName, container));
160 return generatedTypes;
163 private List<Type> allListsToGenTypes(final Module module) {
164 if (module == null) {
165 throw new IllegalArgumentException("Module reference cannot be NULL!");
168 if (module.getName() == null) {
169 throw new IllegalArgumentException("Module name cannot be NULL!");
172 if (module.getChildNodes() == null) {
173 throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
174 + " cannot be NULL!");
177 final List<Type> generatedTypes = new ArrayList<>();
178 final DataNodeIterator it = new DataNodeIterator(module);
179 final List<ListSchemaNode> schemaLists = it.allLists();
180 final String basePackageName = moduleNamespaceToPackageName(module);
181 if (schemaLists != null) {
182 for (final ListSchemaNode list : schemaLists) {
183 generatedTypes.addAll(listToGenType(basePackageName, list));
186 return generatedTypes;
189 private List<GeneratedType> allChoicesToGenTypes(final Module module) {
190 if (module == null) {
191 throw new IllegalArgumentException("Module reference cannot be NULL!");
193 if (module.getName() == null) {
194 throw new IllegalArgumentException("Module name cannot be NULL!");
197 final DataNodeIterator it = new DataNodeIterator(module);
198 final List<ChoiceNode> choiceNodes = it.allChoices();
199 final String basePackageName = moduleNamespaceToPackageName(module);
201 final List<GeneratedType> generatedTypes = new ArrayList<>();
202 for (final ChoiceNode choice : choiceNodes) {
203 if (choice != null) {
204 generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice));
207 return generatedTypes;
210 private List<Type> allAugmentsToGenTypes(final Module module) {
211 if (module == null) {
212 throw new IllegalArgumentException("Module reference cannot be NULL!");
214 if (module.getName() == null) {
215 throw new IllegalArgumentException("Module name cannot be NULL!");
217 if (module.getChildNodes() == null) {
218 throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module "
219 + module.getName() + " cannot be NULL!");
222 final List<Type> generatedTypes = new ArrayList<>();
223 final String basePackageName = moduleNamespaceToPackageName(module);
224 final List<AugmentationSchema> augmentations = resolveAugmentations(module);
225 for (final AugmentationSchema augment : augmentations) {
226 generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment));
228 return generatedTypes;
231 private List<AugmentationSchema> resolveAugmentations(final Module module) {
232 if (module == null) {
233 throw new IllegalArgumentException("Module reference cannot be NULL!");
235 if (module.getAugmentations() == null) {
236 throw new IllegalStateException("Augmentations Set cannot be NULL!");
239 final Set<AugmentationSchema> augmentations = module.getAugmentations();
240 final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);
241 Collections.sort(sortedAugmentations, new Comparator<AugmentationSchema>() {
244 public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) {
246 if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) {
248 } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) {
256 return sortedAugmentations;
259 private GeneratedType moduleToDataType(final Module module) {
260 if (module == null) {
261 throw new IllegalArgumentException("Module reference cannot be NULL!");
264 final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
266 final String basePackageName = moduleNamespaceToPackageName(module);
267 if (moduleDataTypeBuilder != null) {
268 final Set<DataSchemaNode> dataNodes = module.getChildNodes();
269 resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes);
271 return moduleDataTypeBuilder.toInstance();
274 private List<Type> allRPCMethodsToGenType(final Module module) {
275 if (module == null) {
276 throw new IllegalArgumentException("Module reference cannot be NULL!");
279 if (module.getName() == null) {
280 throw new IllegalArgumentException("Module name cannot be NULL!");
283 if (module.getChildNodes() == null) {
284 throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module "
285 + module.getName() + " cannot be NULL!");
288 final String basePackageName = moduleNamespaceToPackageName(module);
289 final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
290 final List<Type> genRPCTypes = new ArrayList<>();
291 final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service");
292 final Type future = Types.typeForClass(Future.class);
293 for (final RpcDefinition rpc : rpcDefinitions) {
296 String rpcName = parseToClassName(rpc.getQName().getLocalName());
297 MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcName);
299 final List<DataNodeIterator> rpcInOut = new ArrayList<>();
301 ContainerSchemaNode input = rpc.getInput();
302 ContainerSchemaNode output = rpc.getOutput();
305 rpcInOut.add(new DataNodeIterator(input));
306 GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
307 resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());
308 Type inTypeInstance = inType.toInstance();
309 genRPCTypes.add(inTypeInstance);
310 method.addParameter(inTypeInstance, "input");
313 Type outTypeInstance = Types.typeForClass(Void.class);
314 if (output != null) {
315 rpcInOut.add(new DataNodeIterator(output));
317 GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
318 resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());
319 outTypeInstance = outType.toInstance();
320 genRPCTypes.add(outTypeInstance);
324 final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance);
325 method.setReturnType(Types.parameterizedTypeFor(future, rpcRes));
326 for (DataNodeIterator it : rpcInOut) {
327 List<ContainerSchemaNode> nContainers = it.allContainers();
328 if ((nContainers != null) && !nContainers.isEmpty()) {
329 for (final ContainerSchemaNode container : nContainers) {
330 genRPCTypes.add(containerToGenType(basePackageName, container));
333 List<ListSchemaNode> nLists = it.allLists();
334 if ((nLists != null) && !nLists.isEmpty()) {
335 for (final ListSchemaNode list : nLists) {
336 genRPCTypes.addAll(listToGenType(basePackageName, list));
342 genRPCTypes.add(interfaceBuilder.toInstance());
346 private List<Type> allNotificationsToGenType(final Module module) {
347 if (module == null) {
348 throw new IllegalArgumentException("Module reference cannot be NULL!");
351 if (module.getName() == null) {
352 throw new IllegalArgumentException("Module name cannot be NULL!");
355 if (module.getChildNodes() == null) {
356 throw new IllegalArgumentException("Reference to Set of Notification Definitions in module "
357 + module.getName() + " cannot be NULL!");
360 final String basePackageName = moduleNamespaceToPackageName(module);
361 final List<Type> genNotifyTypes = new ArrayList<>();
362 final Set<NotificationDefinition> notifications = module.getNotifications();
364 for (final NotificationDefinition notification : notifications) {
365 if (notification != null) {
366 DataNodeIterator it = new DataNodeIterator(notification);
369 for (ContainerSchemaNode node : it.allContainers()) {
370 genNotifyTypes.add(containerToGenType(basePackageName, node));
373 for (ListSchemaNode node : it.allLists()) {
374 genNotifyTypes.addAll(listToGenType(basePackageName, node));
376 final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName,
378 notificationTypeBuilder.addImplementsType(Types.typeForClass(Notification.class));
379 // Notification object
380 resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes());
381 genNotifyTypes.add(notificationTypeBuilder.toInstance());
384 return genNotifyTypes;
387 private List<Type> allIdentitiesToGenTypes(final Module module, final SchemaContext context) {
388 List<Type> genTypes = new ArrayList<>();
390 final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
392 final String basePackageName = moduleNamespaceToPackageName(module);
394 if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
395 for (final IdentitySchemaNode identity : schemaIdentities) {
396 genTypes.add(identityToGenType(basePackageName, identity, context));
402 private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity,
403 final SchemaContext context) {
404 if (identity == null) {
408 final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
409 final String genTypeName = parseToClassName(identity.getQName().getLocalName());
410 final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
412 IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
413 if (baseIdentity != null) {
414 Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
416 final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
417 final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName());
419 GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
420 newType.setExtendsType(gto);
422 newType.setExtendsType(Types.getBaseIdentityTO());
424 newType.setAbstract(true);
425 return newType.toInstance();
428 private List<Type> allGroupingsToGenTypes(final Module module) {
429 final List<Type> genTypes = new ArrayList<>();
430 final String basePackageName = moduleNamespaceToPackageName(module);
431 final Set<GroupingDefinition> groupings = module.getGroupings();
432 if (groupings != null && !groupings.isEmpty()) {
433 for (final GroupingDefinition grouping : groupings) {
434 genTypes.add(groupingToGenType(basePackageName, grouping));
440 private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) {
441 if (grouping == null) {
445 final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath());
446 final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();
447 final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping);
449 resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
450 return typeBuilder.toInstance();
453 private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition<?> typeDefinition) {
454 if (typeDefinition != null) {
455 if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
456 return (EnumTypeDefinition) typeDefinition.getBaseType();
457 } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
458 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
464 private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
465 final GeneratedTypeBuilder typeBuilder) {
466 if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)
467 && (enumTypeDef.getQName().getLocalName() != null)) {
469 final String enumerationName = parseToClassName(enumName);
470 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
472 if (enumBuilder != null) {
473 final List<EnumPair> enums = enumTypeDef.getValues();
476 for (final EnumPair enumPair : enums) {
477 if (enumPair != null) {
478 final String enumPairName = parseToClassName(enumPair.getName());
479 Integer enumPairValue = enumPair.getValue();
481 if (enumPairValue == null) {
482 enumPairValue = listIndex;
484 enumBuilder.addValue(enumPairName, enumPairValue);
495 private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) {
496 if (module == null) {
497 throw new IllegalArgumentException("Module reference cannot be NULL!");
499 String packageName = moduleNamespaceToPackageName(module);
500 final String moduleName = parseToClassName(module.getName()) + postfix;
502 return new GeneratedTypeBuilderImpl(packageName, moduleName);
506 private List<Type> augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) {
507 if (augmentPackageName == null) {
508 throw new IllegalArgumentException("Package Name cannot be NULL!");
510 if (augSchema == null) {
511 throw new IllegalArgumentException("Augmentation Schema cannot be NULL!");
513 if (augSchema.getTargetPath() == null) {
514 throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL).");
517 final List<Type> genTypes = new ArrayList<>();
519 // EVERY augmented interface will extends Augmentation<T> interface
520 // and DataObject interface!!!
521 final SchemaPath targetPath = augSchema.getTargetPath();
522 final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
523 if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
524 && (targetSchemaNode.getQName().getLocalName() != null)) {
525 final Module targetModule = findParentModule(schemaContext, targetSchemaNode);
526 final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
527 final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());
528 final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();
529 final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
531 if (!(targetSchemaNode instanceof ChoiceNode)) {
532 final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
533 targetPackageName, targetSchemaNodeName, augSchema);
534 final GeneratedType augType = augTypeBuilder.toInstance();
535 genTypes.add(augType);
537 final Type refChoiceType = new ReferencedTypeImpl(targetPackageName,
538 parseToClassName(targetSchemaNodeName));
539 final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode;
540 final Set<ChoiceCaseNode> choiceCaseNodes = choiceTarget.getCases();
541 genTypes.addAll(augmentCasesToGenTypes(augmentPackageName, refChoiceType, choiceCaseNodes));
543 genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));
548 private List<GeneratedType> augmentCasesToGenTypes(final String augmentPackageName, final Type refChoiceType,
549 final Set<ChoiceCaseNode> choiceCaseNodes) {
550 if (augmentPackageName == null) {
551 throw new IllegalArgumentException("Augment Package Name string cannot be NULL!");
553 if (choiceCaseNodes == null) {
554 throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
556 final List<GeneratedType> genTypes = generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType,
561 private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName,
562 final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) {
563 final String targetTypeName = parseToClassName(targetSchemaNodeName);
564 Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
565 if (augmentBuilders == null) {
566 augmentBuilders = new HashMap<>();
567 genTypeBuilders.put(augmentPackageName, augmentBuilders);
570 final String augTypeName = augGenTypeName(augmentBuilders, targetTypeName);
571 final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName);
572 final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
574 final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
576 augTypeBuilder.addImplementsType(Types.DATA_OBJECT);
577 augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
579 augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes);
580 augmentBuilders.put(augTypeName, augTypeBuilder);
581 return augTypeBuilder;
584 private List<Type> augmentationBodyToGenTypes(final String augBasePackageName,
585 final Set<DataSchemaNode> augChildNodes) {
586 final List<Type> genTypes = new ArrayList<>();
587 final List<DataNodeIterator> augSchemaIts = new ArrayList<>();
588 for (final DataSchemaNode childNode : augChildNodes) {
589 if (childNode instanceof DataNodeContainer) {
590 augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode));
592 if (childNode instanceof ContainerSchemaNode) {
593 genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode));
594 } else if (childNode instanceof ListSchemaNode) {
595 genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));
597 } else if (childNode instanceof ChoiceNode) {
598 final ChoiceNode choice = (ChoiceNode) childNode;
599 for (final ChoiceCaseNode caseNode : choice.getCases()) {
600 augSchemaIts.add(new DataNodeIterator(caseNode));
602 genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode));
606 for (final DataNodeIterator it : augSchemaIts) {
607 final List<ContainerSchemaNode> augContainers = it.allContainers();
608 final List<ListSchemaNode> augLists = it.allLists();
609 final List<ChoiceNode> augChoices = it.allChoices();
611 if (augContainers != null) {
612 for (final ContainerSchemaNode container : augContainers) {
613 genTypes.add(containerToGenType(augBasePackageName, container));
616 if (augLists != null) {
617 for (final ListSchemaNode list : augLists) {
618 genTypes.addAll(listToGenType(augBasePackageName, list));
621 if (augChoices != null) {
622 for (final ChoiceNode choice : augChoices) {
623 genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice));
630 private String augGenTypeName(final Map<String, GeneratedTypeBuilder> builders, final String genTypeName) {
631 String augTypeName = genTypeName;
634 while ((builders != null) && builders.containsKey(genTypeName + index)) {
637 augTypeName += index;
641 private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) {
642 if (containerNode == null) {
646 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
647 final Set<DataSchemaNode> schemaNodes = containerNode.getChildNodes();
648 final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode);
650 resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
651 return typeBuilder.toInstance();
654 private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName,
655 final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
656 if ((schemaNodes != null) && (typeBuilder != null)) {
657 for (final DataSchemaNode schemaNode : schemaNodes) {
658 if (schemaNode.isAugmenting()) {
661 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
667 private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName,
668 final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
669 if ((schemaNodes != null) && (typeBuilder != null)) {
670 for (final DataSchemaNode schemaNode : schemaNodes) {
671 if (schemaNode.isAugmenting()) {
672 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
679 private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode,
680 final GeneratedTypeBuilder typeBuilder) {
681 if (schemaNode != null && typeBuilder != null) {
682 if (schemaNode instanceof LeafSchemaNode) {
683 resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode);
684 } else if (schemaNode instanceof LeafListSchemaNode) {
685 resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
686 } else if (schemaNode instanceof ContainerSchemaNode) {
687 resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
688 } else if (schemaNode instanceof ListSchemaNode) {
689 resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
690 } else if (schemaNode instanceof ChoiceNode) {
691 resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode);
696 private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
697 final ChoiceNode choiceNode) {
698 if (basePackageName == null) {
699 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
701 if (typeBuilder == null) {
702 throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
704 if (choiceNode == null) {
705 throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
708 final String choiceName = choiceNode.getQName().getLocalName();
709 if (choiceName != null) {
710 final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
711 final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);
712 constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType);
716 private List<GeneratedType> choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) {
717 if (basePackageName == null) {
718 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
720 if (choiceNode == null) {
721 throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
724 final List<GeneratedType> generatedTypes = new ArrayList<>();
725 final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
726 final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
727 choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT);
728 final GeneratedType choiceType = choiceTypeBuilder.toInstance();
730 generatedTypes.add(choiceType);
731 final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();
732 if ((caseNodes != null) && !caseNodes.isEmpty()) {
733 generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes));
735 return generatedTypes;
738 private List<GeneratedType> generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType,
739 final Set<ChoiceCaseNode> caseNodes) {
740 if (basePackageName == null) {
741 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
743 if (refChoiceType == null) {
744 throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
746 if (caseNodes == null) {
747 throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
750 final List<GeneratedType> generatedTypes = new ArrayList<>();
751 for (final ChoiceCaseNode caseNode : caseNodes) {
752 if (caseNode != null && !caseNode.isAddedByUses()) {
753 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
754 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
755 caseTypeBuilder.addImplementsType(refChoiceType);
757 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
758 if (childNodes != null) {
759 resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
761 generatedTypes.add(caseTypeBuilder.toInstance());
765 return generatedTypes;
768 private List<GeneratedType> generateTypesFromAugmentedChoiceCases(final String basePackageName,
769 final Type refChoiceType, final Set<ChoiceCaseNode> caseNodes) {
770 if (basePackageName == null) {
771 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
773 if (refChoiceType == null) {
774 throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
776 if (caseNodes == null) {
777 throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
780 final List<GeneratedType> generatedTypes = new ArrayList<>();
781 for (final ChoiceCaseNode caseNode : caseNodes) {
782 if (caseNode != null && caseNode.isAugmenting()) {
783 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
784 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
785 caseTypeBuilder.addImplementsType(refChoiceType);
787 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
788 if (childNodes != null) {
789 resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
791 generatedTypes.add(caseTypeBuilder.toInstance());
795 return generatedTypes;
798 private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
799 if ((leaf != null) && (typeBuilder != null)) {
800 final String leafName = leaf.getQName().getLocalName();
801 String leafDesc = leaf.getDescription();
802 if (leafDesc == null) {
806 if (leafName != null) {
807 final TypeDefinition<?> typeDef = leaf.getType();
809 Type returnType = null;
810 if (!(typeDef instanceof EnumTypeDefinition)) {
811 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
813 final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
814 final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName,
817 if (enumBuilder != null) {
818 returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
820 ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
822 if (returnType != null) {
823 constructGetter(typeBuilder, leafName, leafDesc, returnType);
824 if (!leaf.isConfiguration()) {
825 constructSetter(typeBuilder, leafName, leafDesc, returnType);
834 private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
835 boolean isReadOnly) {
836 if ((leaf != null) && (toBuilder != null)) {
837 final String leafName = leaf.getQName().getLocalName();
838 String leafDesc = leaf.getDescription();
839 if (leafDesc == null) {
843 if (leafName != null) {
844 final TypeDefinition<?> typeDef = leaf.getType();
846 // TODO: properly resolve enum types
847 final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
849 if (returnType != null) {
850 final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName));
852 propBuilder.setReadOnly(isReadOnly);
853 propBuilder.setReturnType(returnType);
854 propBuilder.setComment(leafDesc);
856 toBuilder.addEqualsIdentity(propBuilder);
857 toBuilder.addHashIdentity(propBuilder);
858 toBuilder.addToStringProperty(propBuilder);
867 private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {
868 if ((node != null) && (typeBuilder != null)) {
869 final String nodeName = node.getQName().getLocalName();
870 String nodeDesc = node.getDescription();
871 if (nodeDesc == null) {
875 if (nodeName != null) {
876 final TypeDefinition<?> type = node.getType();
877 final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type));
879 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
880 if (!node.isConfiguration()) {
881 constructSetter(typeBuilder, nodeName, nodeDesc, listType);
889 private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
890 final ContainerSchemaNode containerNode) {
891 if ((containerNode != null) && (typeBuilder != null)) {
892 final String nodeName = containerNode.getQName().getLocalName();
894 if (nodeName != null) {
895 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
897 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);
898 constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType);
906 private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
907 final ListSchemaNode schemaNode) {
908 if ((schemaNode != null) && (typeBuilder != null)) {
909 final String listName = schemaNode.getQName().getLocalName();
911 if (listName != null) {
912 final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());
913 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);
914 constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
915 if (!schemaNode.isConfiguration()) {
916 constructSetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
925 * Method instantiates new Generated Type Builder and sets the implements
926 * definitions of Data Object and Augmentable.
929 * Generated Type Package Name
931 * Schema Node definition
932 * @return Generated Type Builder instance for Schema Node definition
934 private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
935 final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");
936 builder.addImplementsType(Types.DATA_OBJECT);
937 builder.addImplementsType(Types.augmentableTypeFor(builder));
947 private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
948 return addRawInterfaceDefinition(packageName, schemaNode, "");
951 private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,
952 final String prefix) {
953 if (schemaNode == null) {
954 throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
956 if (packageName == null) {
957 throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
959 if (schemaNode.getQName() == null) {
960 throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!");
962 final String schemaNodeName = schemaNode.getQName().getLocalName();
963 if (schemaNodeName == null) {
964 throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!");
967 final String genTypeName;
968 if (prefix == null) {
969 genTypeName = parseToClassName(schemaNodeName);
971 genTypeName = prefix + parseToClassName(schemaNodeName);
974 final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
975 if (!genTypeBuilders.containsKey(packageName)) {
976 final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
977 builders.put(genTypeName, newType);
978 genTypeBuilders.put(packageName, builders);
980 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
981 if (!builders.containsKey(genTypeName)) {
982 builders.put(genTypeName, newType);
988 private String getterMethodName(final String methodName) {
989 final StringBuilder method = new StringBuilder();
990 method.append("get");
991 method.append(parseToClassName(methodName));
992 return method.toString();
995 private String setterMethodName(final String methodName) {
996 final StringBuilder method = new StringBuilder();
997 method.append("set");
998 method.append(parseToClassName(methodName));
999 return method.toString();
1002 private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,
1003 final String schemaNodeName, final String comment, final Type returnType) {
1004 final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName));
1006 getMethod.setComment(comment);
1007 getMethod.setReturnType(returnType);
1012 private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder,
1013 final String schemaNodeName, final String comment, final Type parameterType) {
1014 final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName));
1016 setMethod.setComment(comment);
1017 setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName));
1018 setMethod.setReturnType(Types.voidType());
1023 private List<Type> listToGenType(final String basePackageName, final ListSchemaNode list) {
1024 if (basePackageName == null) {
1025 throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1028 throw new IllegalArgumentException("List Schema Node cannot be NULL!");
1031 final String packageName = packageNameForGeneratedType(basePackageName, list.getPath());
1032 final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list);
1033 final List<String> listKeys = listKeys(list);
1034 GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys);
1036 final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
1038 for (final DataSchemaNode schemaNode : schemaNodes) {
1039 if (schemaNode.isAugmenting()) {
1042 addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys);
1044 return typeBuildersToGenTypes(typeBuilder, genTOBuilder);
1047 private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode,
1048 final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
1049 if (schemaNode == null) {
1050 throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
1053 if (typeBuilder == null) {
1054 throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1057 if (schemaNode instanceof LeafSchemaNode) {
1058 final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
1059 if (!isPartOfListKey(leaf, listKeys)) {
1060 resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
1062 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
1064 } else if (schemaNode instanceof LeafListSchemaNode) {
1065 resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
1066 } else if (schemaNode instanceof ContainerSchemaNode) {
1067 resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
1068 } else if (schemaNode instanceof ListSchemaNode) {
1069 resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
1073 private List<Type> typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {
1074 final List<Type> genTypes = new ArrayList<>();
1075 if (typeBuilder == null) {
1076 throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
1079 if (genTOBuilder != null) {
1080 final GeneratedTransferObject genTO = genTOBuilder.toInstance();
1081 constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO);
1082 genTypes.add(genTO);
1084 genTypes.add(typeBuilder.toInstance());
1092 private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) {
1093 final String listName = list.getQName().getLocalName() + "Key";
1094 return schemaNodeToTransferObjectBuilder(packageName, list, listName);
1097 private boolean isPartOfListKey(final LeafSchemaNode leaf, final List<String> keys) {
1098 if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
1099 final String leafName = leaf.getQName().getLocalName();
1100 if (keys.contains(leafName)) {
1107 private List<String> listKeys(final ListSchemaNode list) {
1108 final List<String> listKeys = new ArrayList<>();
1110 if (list.getKeyDefinition() != null) {
1111 final List<QName> keyDefinitions = list.getKeyDefinition();
1113 for (final QName keyDefinition : keyDefinitions) {
1114 listKeys.add(keyDefinition.getLocalName());
1120 private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) {
1121 if (packageName == null) {
1122 throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
1125 throw new IllegalArgumentException("List Schema Node cannot be NULL!");
1128 final String schemaNodeName = list.getQName().getLocalName();
1129 final String genTypeName = parseToClassName(schemaNodeName);
1131 GeneratedTypeBuilder typeBuilder = null;
1132 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
1133 if (builders != null) {
1134 typeBuilder = builders.get(genTypeName);
1136 if (typeBuilder == null) {
1137 typeBuilder = addDefaultInterfaceDefinition(packageName, list);
1142 private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list,
1143 final List<String> listKeys) {
1144 GeneratedTOBuilder genTOBuilder = null;
1145 if (listKeys.size() > 0) {
1146 genTOBuilder = resolveListKey(packageName, list);
1148 return genTOBuilder;