ea3b472710fbeb84b4783396ee0e73809d274b56
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.yangtools.sal.binding.generator.impl;\r
9 \r
10 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;\r
11 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;\r
12 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName;\r
13 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;\r
14 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.schemaNodeToTransferObjectBuilder;\r
15 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;\r
16 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;\r
17 \r
18 import java.net.URI;\r
19 import java.net.URISyntaxException;\r
20 import java.util.ArrayList;\r
21 import java.util.Collections;\r
22 import java.util.Comparator;\r
23 import java.util.HashMap;\r
24 import java.util.List;\r
25 import java.util.Map;\r
26 import java.util.Set;\r
27 import java.util.concurrent.Future;\r
28 \r
29 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;\r
30 import org.opendaylight.yangtools.binding.generator.util.Types;\r
31 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;\r
32 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;\r
33 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;\r
34 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;\r
35 import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;\r
36 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;\r
37 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;\r
38 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;\r
39 import org.opendaylight.yangtools.sal.binding.model.api.Type;\r
40 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;\r
41 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;\r
42 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;\r
43 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;\r
44 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder;\r
45 import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort;\r
46 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;\r
47 import org.opendaylight.yangtools.yang.binding.DataRoot;\r
48 import org.opendaylight.yangtools.yang.binding.Identifiable;\r
49 import org.opendaylight.yangtools.yang.binding.Identifier;\r
50 import org.opendaylight.yangtools.yang.binding.RpcService;\r
51 import org.opendaylight.yangtools.yang.common.QName;\r
52 import org.opendaylight.yangtools.yang.common.RpcResult;\r
53 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;\r
54 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;\r
55 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;\r
56 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;\r
57 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;\r
58 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;\r
59 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;\r
60 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;\r
61 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;\r
62 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;\r
63 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;\r
64 import org.opendaylight.yangtools.yang.model.api.Module;\r
65 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;\r
66 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;\r
67 import org.opendaylight.yangtools.yang.model.api.SchemaContext;\r
68 import org.opendaylight.yangtools.yang.model.api.SchemaNode;\r
69 import org.opendaylight.yangtools.yang.model.api.SchemaPath;\r
70 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;\r
71 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;\r
72 import org.opendaylight.yangtools.yang.model.api.UsesNode;\r
73 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;\r
74 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;\r
75 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;\r
76 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;\r
77 import org.opendaylight.yangtools.yang.model.util.ExtendedType;\r
78 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;\r
79 import org.opendaylight.yangtools.yang.model.util.UnionType;\r
80 \r
81 public final class BindingGeneratorImpl implements BindingGenerator {\r
82 \r
83     /**\r
84      * Outter key represents the package name. Outter value represents map of\r
85      * all builders in the same package. Inner key represents the schema node\r
86      * name (in JAVA class/interface name format). Inner value represents\r
87      * instance of builder for schema node specified in key part.\r
88      */\r
89     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;\r
90 \r
91     /**\r
92      * Provide methods for converting YANG types to JAVA types.\r
93      */\r
94     private TypeProvider typeProvider;\r
95 \r
96     /**\r
97      * Holds reference to schema context to resolve data of augmented elemnt\r
98      * when creating augmentation builder\r
99      */\r
100     private SchemaContext schemaContext;\r
101 \r
102     /**\r
103      * Each grouping which is converted from schema node to generated type is\r
104      * added to this map with its Schema path as key to make it easier to get\r
105      * reference to it. In schema nodes in <code>uses</code> attribute there is\r
106      * only Schema Path but when building list of implemented interfaces for\r
107      * Schema node the object of type <code>Type</code> is required. So in this\r
108      * case is used this map.\r
109      */\r
110     private final Map<SchemaPath, GeneratedType> allGroupings = new HashMap<SchemaPath, GeneratedType>();\r
111 \r
112     /**\r
113      * Only parent constructor is invoked.\r
114      */\r
115     \r
116     private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";\r
117     private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";\r
118     \r
119     public BindingGeneratorImpl() {\r
120         super();\r
121     }\r
122 \r
123     /**\r
124      * Resolves generated types from <code>context</code> schema nodes of all\r
125      * modules.\r
126      * \r
127      * Generated types are created for modules, groupings, types, containers,\r
128      * lists, choices, augments, rpcs, notification, identities.\r
129      * \r
130      * @param context\r
131      *            schema context which contains data about all schema nodes\r
132      *            saved in modules\r
133      * @return list of types (usually <code>GeneratedType</code>\r
134      *         <code>GeneratedTransferObject</code>which are generated from\r
135      *         <code>context</code> data.\r
136      * @throws IllegalArgumentException\r
137      *             if param <code>context</code> is null\r
138      * @throws IllegalStateException\r
139      *             if <code>context</code> contain no modules\r
140      */\r
141     @Override\r
142     public List<Type> generateTypes(final SchemaContext context) {\r
143         if (context == null) {\r
144             throw new IllegalArgumentException("Schema Context reference cannot be NULL!");\r
145         }\r
146         if (context.getModules() == null) {\r
147             throw new IllegalStateException("Schema Context does not contain defined modules!");\r
148         }\r
149 \r
150         final List<Type> generatedTypes = new ArrayList<>();\r
151         schemaContext = context;\r
152         typeProvider = new TypeProviderImpl(context);\r
153         final Set<Module> modules = context.getModules();\r
154         genTypeBuilders = new HashMap<>();\r
155         for (final Module module : modules) {\r
156 \r
157             generatedTypes.addAll(allGroupingsToGenTypes(module));\r
158 \r
159             if (false == module.getChildNodes().isEmpty()) {\r
160                 generatedTypes.add(moduleToDataType(module));\r
161             }\r
162             generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));\r
163             generatedTypes.addAll(allContainersToGenTypes(module));\r
164             generatedTypes.addAll(allListsToGenTypes(module));\r
165             generatedTypes.addAll(allChoicesToGenTypes(module));\r
166             generatedTypes.addAll(allAugmentsToGenTypes(module));\r
167             generatedTypes.addAll(allRPCMethodsToGenType(module));\r
168             generatedTypes.addAll(allNotificationsToGenType(module));\r
169             generatedTypes.addAll(allIdentitiesToGenTypes(module, context));\r
170 \r
171         }\r
172         return generatedTypes;\r
173     }\r
174 \r
175     /**\r
176      * Resolves generated types from <code>context</code> schema nodes only for\r
177      * modules specified in <code>modules</code>\r
178      * \r
179      * Generated types are created for modules, groupings, types, containers,\r
180      * lists, choices, augments, rpcs, notification, identities.\r
181      * \r
182      * @param context\r
183      *            schema context which contains data about all schema nodes\r
184      *            saved in modules\r
185      * @param modules\r
186      *            set of modules for which schema nodes should be generated\r
187      *            types\r
188      * @return list of types (usually <code>GeneratedType</code> or\r
189      *         <code>GeneratedTransferObject</code>) which:\r
190      *         <ul>\r
191      *         <li>are generated from <code>context</code> schema nodes and</li>\r
192      *         <li>are also part of some of the module in <code>modules</code>\r
193      *         set</li>.\r
194      *         </ul>\r
195      * @throws IllegalArgumentException\r
196      *             <ul>\r
197      *             <li>if param <code>context</code> is null or</li>\r
198      *             <li>if param <code>modules</code> is null</li>\r
199      *             </ul>\r
200      * @throws IllegalStateException\r
201      *             if <code>context</code> contain no modules\r
202      */\r
203     @Override\r
204     public List<Type> generateTypes(final SchemaContext context, final Set<Module> modules) {\r
205         if (context == null) {\r
206             throw new IllegalArgumentException("Schema Context reference cannot be NULL!");\r
207         }\r
208         if (context.getModules() == null) {\r
209             throw new IllegalStateException("Schema Context does not contain defined modules!");\r
210         }\r
211         if (modules == null) {\r
212             throw new IllegalArgumentException("Sef of Modules cannot be NULL!");\r
213         }\r
214 \r
215         final List<Type> filteredGenTypes = new ArrayList<>();\r
216         schemaContext = context;\r
217         typeProvider = new TypeProviderImpl(context);\r
218         final Set<Module> contextModules = context.getModules();\r
219         genTypeBuilders = new HashMap<>();\r
220         for (final Module contextModule : contextModules) {\r
221             final List<Type> generatedTypes = new ArrayList<>();\r
222 \r
223             generatedTypes.addAll(allGroupingsToGenTypes(contextModule));\r
224             if (false == contextModule.getChildNodes().isEmpty()) {\r
225                 generatedTypes.add(moduleToDataType(contextModule));\r
226             }\r
227             generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));\r
228             generatedTypes.addAll(allContainersToGenTypes(contextModule));\r
229             generatedTypes.addAll(allListsToGenTypes(contextModule));\r
230             generatedTypes.addAll(allChoicesToGenTypes(contextModule));\r
231             generatedTypes.addAll(allAugmentsToGenTypes(contextModule));\r
232             generatedTypes.addAll(allRPCMethodsToGenType(contextModule));\r
233             generatedTypes.addAll(allNotificationsToGenType(contextModule));\r
234             generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));\r
235 \r
236             if (modules.contains(contextModule)) {\r
237                 filteredGenTypes.addAll(generatedTypes);\r
238             }\r
239         }\r
240         return filteredGenTypes;\r
241     }\r
242 \r
243     /**\r
244      * Converts all extended type definitions of module to the list of\r
245      * <code>Type</code> objects.\r
246      * \r
247      * @param module\r
248      *            module from which is obtained set of type definitions\r
249      * @return list of <code>Type</code> which are generated from extended\r
250      *         definition types (object of type <code>ExtendedType</code>)\r
251      * @throws IllegalArgumentException\r
252      *             <ul>\r
253      *             <li>if module equals null</li>\r
254      *             <li>if name of module equals null</li>\r
255      *             <li>if type definitions of module equal null</li>\r
256      *             </ul>\r
257      * \r
258      */\r
259     private List<Type> allTypeDefinitionsToGenTypes(final Module module) {\r
260         if (module == null) {\r
261             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
262         }\r
263         if (module.getName() == null) {\r
264             throw new IllegalArgumentException("Module name cannot be NULL!");\r
265         }\r
266         if (module.getTypeDefinitions() == null) {\r
267             throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!");\r
268         }\r
269 \r
270         final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();\r
271         final List<Type> generatedTypes = new ArrayList<>();\r
272         for (final TypeDefinition<?> typedef : typeDefinitions) {\r
273             if (typedef != null) {\r
274                 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef);\r
275                 if ((type != null) && !generatedTypes.contains(type)) {\r
276                     generatedTypes.add(type);\r
277                 }\r
278             }\r
279         }\r
280         return generatedTypes;\r
281     }\r
282 \r
283     /**\r
284      * Converts all <b>containers</b> of the module to the list of\r
285      * <code>Type</code> objects.\r
286      * \r
287      * @param module\r
288      *            module from which is obtained DataNodeIterator to iterate over\r
289      *            all containers\r
290      * @return list of <code>Type</code> which are generated from containers\r
291      *         (objects of type <code>ContainerSchemaNode</code>)\r
292      * @throws IllegalArgumentException\r
293      *             <ul>\r
294      *             <li>if the module equals null</li>\r
295      *             <li>if the name of module equals null</li>\r
296      *             <li>if the set of child nodes equals null</li>\r
297      *             </ul>\r
298      * \r
299      */\r
300     private List<Type> allContainersToGenTypes(final Module module) {\r
301         if (module == null) {\r
302             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
303         }\r
304 \r
305         if (module.getName() == null) {\r
306             throw new IllegalArgumentException("Module name cannot be NULL!");\r
307         }\r
308 \r
309         if (module.getChildNodes() == null) {\r
310             throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()\r
311                     + " cannot be NULL!");\r
312         }\r
313 \r
314         final List<Type> generatedTypes = new ArrayList<>();\r
315         final DataNodeIterator it = new DataNodeIterator(module);\r
316         final List<ContainerSchemaNode> schemaContainers = it.allContainers();\r
317         final String basePackageName = moduleNamespaceToPackageName(module);\r
318         for (final ContainerSchemaNode container : schemaContainers) {\r
319             if (!container.isAddedByUses()) {\r
320                 generatedTypes.add(containerToGenType(basePackageName, container));\r
321             }\r
322         }\r
323         return generatedTypes;\r
324     }\r
325 \r
326     /**\r
327      * Converts all <b>lists</b> of the module to the list of <code>Type</code>\r
328      * objects.\r
329      * \r
330      * @param module\r
331      *            module from which is obtained DataNodeIterator to iterate over\r
332      *            all lists\r
333      * @return list of <code>Type</code> which are generated from lists (objects\r
334      *         of type <code>ListSchemaNode</code>)\r
335      * @throws IllegalArgumentException\r
336      *             <ul>\r
337      *             <li>if the module equals null</li>\r
338      *             <li>if the name of module equals null</li>\r
339      *             <li>if the set of child nodes equals null</li>\r
340      *             </ul>\r
341      * \r
342      */\r
343     private List<Type> allListsToGenTypes(final Module module) {\r
344         if (module == null) {\r
345             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
346         }\r
347 \r
348         if (module.getName() == null) {\r
349             throw new IllegalArgumentException("Module name cannot be NULL!");\r
350         }\r
351 \r
352         if (module.getChildNodes() == null) {\r
353             throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()\r
354                     + " cannot be NULL!");\r
355         }\r
356 \r
357         final List<Type> generatedTypes = new ArrayList<>();\r
358         final DataNodeIterator it = new DataNodeIterator(module);\r
359         final List<ListSchemaNode> schemaLists = it.allLists();\r
360         final String basePackageName = moduleNamespaceToPackageName(module);\r
361         if (schemaLists != null) {\r
362             for (final ListSchemaNode list : schemaLists) {\r
363                 if (!list.isAddedByUses()) {\r
364                     generatedTypes.addAll(listToGenType(basePackageName, list));\r
365                 }\r
366             }\r
367         }\r
368         return generatedTypes;\r
369     }\r
370 \r
371     /**\r
372      * Converts all <b>choices</b> of the module to the list of\r
373      * <code>Type</code> objects.\r
374      * \r
375      * @param module\r
376      *            module from which is obtained DataNodeIterator to iterate over\r
377      *            all choices\r
378      * @return list of <code>Type</code> which are generated from choices\r
379      *         (objects of type <code>ChoiceNode</code>)\r
380      * @throws IllegalArgumentException\r
381      *             <ul>\r
382      *             <li>if the module equals null</li>\r
383      *             <li>if the name of module equals null</li> *\r
384      *             </ul>\r
385      * \r
386      */\r
387     private List<GeneratedType> allChoicesToGenTypes(final Module module) {\r
388         if (module == null) {\r
389             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
390         }\r
391         if (module.getName() == null) {\r
392             throw new IllegalArgumentException("Module name cannot be NULL!");\r
393         }\r
394 \r
395         final DataNodeIterator it = new DataNodeIterator(module);\r
396         final List<ChoiceNode> choiceNodes = it.allChoices();\r
397         final String basePackageName = moduleNamespaceToPackageName(module);\r
398 \r
399         final List<GeneratedType> generatedTypes = new ArrayList<>();\r
400         for (final ChoiceNode choice : choiceNodes) {\r
401             if ((choice != null) && !choice.isAddedByUses()) {\r
402                 generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice));\r
403             }\r
404         }\r
405         return generatedTypes;\r
406     }\r
407 \r
408     /**\r
409      * Converts all <b>augmentation</b> of the module to the list\r
410      * <code>Type</code> objects.\r
411      * \r
412      * @param module\r
413      *            module from which is obtained list of all augmentation objects\r
414      *            to iterate over them\r
415      * @return list of <code>Type</code> which are generated from augments\r
416      *         (objects of type <code>AugmentationSchema</code>)\r
417      * @throws IllegalArgumentException\r
418      *             <ul>\r
419      *             <li>if the module equals null</li>\r
420      *             <li>if the name of module equals null</li>\r
421      *             <li>if the set of child nodes equals null</li>\r
422      *             </ul>\r
423      * \r
424      */\r
425     private List<Type> allAugmentsToGenTypes(final Module module) {\r
426         if (module == null) {\r
427             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
428         }\r
429         if (module.getName() == null) {\r
430             throw new IllegalArgumentException("Module name cannot be NULL!");\r
431         }\r
432         if (module.getChildNodes() == null) {\r
433             throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module "\r
434                     + module.getName() + " cannot be NULL!");\r
435         }\r
436 \r
437         final List<Type> generatedTypes = new ArrayList<>();\r
438         final String basePackageName = moduleNamespaceToPackageName(module);\r
439         final List<AugmentationSchema> augmentations = resolveAugmentations(module);\r
440         for (final AugmentationSchema augment : augmentations) {\r
441             generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment));\r
442         }\r
443         return generatedTypes;\r
444     }\r
445 \r
446     /**\r
447      * Returns list of <code>AugmentationSchema</code> objects. The objects are\r
448      * sorted according to the length of their target path from the shortest to\r
449      * the longest.\r
450      * \r
451      * @param module\r
452      *            module from which is obtained list of all augmentation objects\r
453      * @return list of sorted <code>AugmentationSchema</code> objects obtained\r
454      *         from <code>module</code>\r
455      * @throws IllegalArgumentException\r
456      *             <ul>\r
457      *             <li>if the module equals null</li>\r
458      *             <li>if the set of augmentation equals null</li>\r
459      *             </ul>\r
460      * \r
461      */\r
462     private List<AugmentationSchema> resolveAugmentations(final Module module) {\r
463         if (module == null) {\r
464             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
465         }\r
466         if (module.getAugmentations() == null) {\r
467             throw new IllegalStateException("Augmentations Set cannot be NULL!");\r
468         }\r
469 \r
470         final Set<AugmentationSchema> augmentations = module.getAugmentations();\r
471         final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);\r
472         Collections.sort(sortedAugmentations, new Comparator<AugmentationSchema>() {\r
473 \r
474             @Override\r
475             public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) {\r
476 \r
477                 if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) {\r
478                     return 1;\r
479                 } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) {\r
480                     return -1;\r
481                 }\r
482                 return 0;\r
483 \r
484             }\r
485         });\r
486 \r
487         return sortedAugmentations;\r
488     }\r
489 \r
490     /**\r
491      * Converts whole <b>module</b> to <code>GeneratedType</code> object.\r
492      * Firstly is created the module builder object from which is finally\r
493      * obtained reference to <code>GeneratedType</code> object.\r
494      * \r
495      * @param module\r
496      *            module from which are obtained the module name, child nodes,\r
497      *            uses and is derived package name\r
498      * @return <code>GeneratedType</code> which is internal representation of\r
499      *         the module\r
500      * @throws IllegalArgumentException\r
501      *             if the module equals null\r
502      * \r
503      */\r
504     private GeneratedType moduleToDataType(final Module module) {\r
505         if (module == null) {\r
506             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
507         }\r
508 \r
509         final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");\r
510         addImplementedInterfaceFromUses(module, moduleDataTypeBuilder);\r
511         moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class));\r
512 \r
513         final String basePackageName = moduleNamespaceToPackageName(module);\r
514         if (moduleDataTypeBuilder != null) {\r
515             final Set<DataSchemaNode> dataNodes = module.getChildNodes();\r
516             resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes);\r
517         }\r
518         return moduleDataTypeBuilder.toInstance();\r
519     }\r
520 \r
521     /**\r
522      * Converts all <b>rpcs</b> inputs and outputs substatements of the module\r
523      * to the list of <code>Type</code> objects. In addition are to containers\r
524      * and lists which belong to input or output also part of returning list.\r
525      * \r
526      * @param module\r
527      *            module from which is obtained set of all rpc objects to\r
528      *            iterate over them\r
529      * @return list of <code>Type</code> which are generated from rpcs inputs,\r
530      *         outputs + container and lists which are part of inputs or outputs\r
531      * @throws IllegalArgumentException\r
532      *             <ul>\r
533      *             <li>if the module equals null</li>\r
534      *             <li>if the name of module equals null</li>\r
535      *             <li>if the set of child nodes equals null</li>\r
536      *             </ul>\r
537      * \r
538      */\r
539     private List<Type> allRPCMethodsToGenType(final Module module) {\r
540         if (module == null) {\r
541             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
542         }\r
543 \r
544         if (module.getName() == null) {\r
545             throw new IllegalArgumentException("Module name cannot be NULL!");\r
546         }\r
547 \r
548         if (module.getChildNodes() == null) {\r
549             throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module "\r
550                     + module.getName() + " cannot be NULL!");\r
551         }\r
552 \r
553         final String basePackageName = moduleNamespaceToPackageName(module);\r
554         final Set<RpcDefinition> rpcDefinitions = module.getRpcs();\r
555 \r
556         if (rpcDefinitions.isEmpty()) {\r
557             return Collections.emptyList();\r
558         }\r
559 \r
560         final List<Type> genRPCTypes = new ArrayList<>();\r
561         final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service");\r
562         interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class));\r
563         final Type future = Types.typeForClass(Future.class);\r
564         for (final RpcDefinition rpc : rpcDefinitions) {\r
565             if (rpc != null) {\r
566 \r
567                 String rpcName = parseToClassName(rpc.getQName().getLocalName());\r
568                 String rpcMethodName = parseToValidParamName(rpcName);\r
569                 MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName);\r
570 \r
571                 final List<DataNodeIterator> rpcInOut = new ArrayList<>();\r
572 \r
573                 ContainerSchemaNode input = rpc.getInput();\r
574                 ContainerSchemaNode output = rpc.getOutput();\r
575 \r
576                 if (input != null) {\r
577                     rpcInOut.add(new DataNodeIterator(input));\r
578                     GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);\r
579                     addImplementedInterfaceFromUses(input, inType);\r
580                     inType.addImplementsType(Types.DATA_OBJECT);\r
581                     resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());\r
582                     Type inTypeInstance = inType.toInstance();\r
583                     genRPCTypes.add(inTypeInstance);\r
584                     method.addParameter(inTypeInstance, "input");\r
585                 }\r
586 \r
587                 Type outTypeInstance = Types.typeForClass(Void.class);\r
588                 if (output != null) {\r
589                     rpcInOut.add(new DataNodeIterator(output));\r
590                     GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);\r
591                     addImplementedInterfaceFromUses(output, outType);\r
592                     outType.addImplementsType(Types.DATA_OBJECT);\r
593                     resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());\r
594                     outTypeInstance = outType.toInstance();\r
595                     genRPCTypes.add(outTypeInstance);\r
596 \r
597                 }\r
598 \r
599                 final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance);\r
600                 method.setReturnType(Types.parameterizedTypeFor(future, rpcRes));\r
601                 for (DataNodeIterator it : rpcInOut) {\r
602                     List<ContainerSchemaNode> nContainers = it.allContainers();\r
603                     if ((nContainers != null) && !nContainers.isEmpty()) {\r
604                         for (final ContainerSchemaNode container : nContainers) {\r
605                             if (!container.isAddedByUses()) {\r
606                                 genRPCTypes.add(containerToGenType(basePackageName, container));\r
607                             }\r
608                         }\r
609                     }\r
610                     List<ListSchemaNode> nLists = it.allLists();\r
611                     if ((nLists != null) && !nLists.isEmpty()) {\r
612                         for (final ListSchemaNode list : nLists) {\r
613                             if (!list.isAddedByUses()) {\r
614                                 genRPCTypes.addAll(listToGenType(basePackageName, list));\r
615                             }\r
616                         }\r
617                     }\r
618                 }\r
619             }\r
620         }\r
621         genRPCTypes.add(interfaceBuilder.toInstance());\r
622         return genRPCTypes;\r
623     }\r
624 \r
625     /**\r
626      * Converts all <b>notifications</b> of the module to the list of\r
627      * <code>Type</code> objects. In addition are to this list added containers\r
628      * and lists which are part of this notification.\r
629      * \r
630      * @param module\r
631      *            module from which is obtained set of all notification objects\r
632      *            to iterate over them\r
633      * @return list of <code>Type</code> which are generated from notification\r
634      *         (object of type <code>NotificationDefinition</code>\r
635      * @throws IllegalArgumentException\r
636      *             <ul>\r
637      *             <li>if the module equals null</li>\r
638      *             <li>if the name of module equals null</li>\r
639      *             <li>if the set of child nodes equals null</li>\r
640      *             </ul>\r
641      * \r
642      */\r
643     private List<Type> allNotificationsToGenType(final Module module) {\r
644         if (module == null) {\r
645             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
646         }\r
647 \r
648         if (module.getName() == null) {\r
649             throw new IllegalArgumentException("Module name cannot be NULL!");\r
650         }\r
651 \r
652         if (module.getChildNodes() == null) {\r
653             throw new IllegalArgumentException("Reference to Set of Notification Definitions in module "\r
654                     + module.getName() + " cannot be NULL!");\r
655         }\r
656 \r
657         final String basePackageName = moduleNamespaceToPackageName(module);\r
658         final List<Type> genNotifyTypes = new ArrayList<>();\r
659         final Set<NotificationDefinition> notifications = module.getNotifications();\r
660 \r
661         for (final NotificationDefinition notification : notifications) {\r
662             if (notification != null) {\r
663                 DataNodeIterator it = new DataNodeIterator(notification);\r
664 \r
665                 // Containers\r
666                 for (ContainerSchemaNode node : it.allContainers()) {\r
667                     if (!node.isAddedByUses()) {\r
668                         genNotifyTypes.add(containerToGenType(basePackageName, node));\r
669                     }\r
670                 }\r
671                 // Lists\r
672                 for (ListSchemaNode node : it.allLists()) {\r
673                     if (!node.isAddedByUses()) {\r
674                         genNotifyTypes.addAll(listToGenType(basePackageName, node));\r
675                     }\r
676                 }\r
677                 final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName,\r
678                         notification);\r
679                 notificationTypeBuilder.addImplementsType(Types\r
680                         .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class));\r
681                 // Notification object\r
682                 resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes());\r
683                 genNotifyTypes.add(notificationTypeBuilder.toInstance());\r
684             }\r
685         }\r
686         return genNotifyTypes;\r
687     }\r
688 \r
689     /**\r
690      * Converts all <b>identities</b> of the module to the list of\r
691      * <code>Type</code> objects.\r
692      * \r
693      * @param module\r
694      *            module from which is obtained set of all identity objects to\r
695      *            iterate over them\r
696      * @param context\r
697      *            schema context only used as input parameter for method\r
698      *            {@link identityToGenType}\r
699      * @return list of <code>Type</code> which are generated from identities\r
700      *         (object of type <code>IdentitySchemaNode</code>\r
701      * \r
702      */\r
703     private List<Type> allIdentitiesToGenTypes(final Module module, final SchemaContext context) {\r
704         List<Type> genTypes = new ArrayList<>();\r
705 \r
706         final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();\r
707 \r
708         final String basePackageName = moduleNamespaceToPackageName(module);\r
709 \r
710         if (schemaIdentities != null && !schemaIdentities.isEmpty()) {\r
711             for (final IdentitySchemaNode identity : schemaIdentities) {\r
712                 genTypes.add(identityToGenType(basePackageName, identity, context));\r
713             }\r
714         }\r
715         return genTypes;\r
716     }\r
717 \r
718     /**\r
719      * Converts the <b>identity</b> object to GeneratedType. Firstly it is\r
720      * created transport object builder. If identity contains base identity then\r
721      * reference to base identity is added to superior identity as its extend.\r
722      * If identity doesn't contain base identity then only reference to abstract\r
723      * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity\r
724      * BaseIdentity} is added\r
725      * \r
726      * @param basePackageName\r
727      *            string containing package name to which identity belongs\r
728      * @param identity\r
729      *            IdentitySchemaNode which contains data about identity\r
730      * @param context\r
731      *            SchemaContext which is used to get package and name\r
732      *            information about base of identity\r
733      * \r
734      * @return GeneratedType which is generated from identity (object of type\r
735      *         <code>IdentitySchemaNode</code>\r
736      * \r
737      */\r
738     private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity,\r
739             final SchemaContext context) {\r
740         if (identity == null) {\r
741             return null;\r
742         }\r
743 \r
744         final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());\r
745         final String genTypeName = parseToClassName(identity.getQName().getLocalName());\r
746         final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName);\r
747 \r
748         IdentitySchemaNode baseIdentity = identity.getBaseIdentity();\r
749         if (baseIdentity != null) {\r
750             Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);\r
751 \r
752             final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);\r
753             final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName());\r
754 \r
755             GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();\r
756             newType.setExtendsType(gto);\r
757         } else {\r
758             newType.setExtendsType(Types.getBaseIdentityTO());\r
759         }\r
760         newType.setAbstract(true);\r
761         return newType.toInstance();\r
762     }\r
763 \r
764     /**\r
765      * Converts all <b>groupings</b> of the module to the list of\r
766      * <code>Type</code> objects. Firstly are groupings sorted according mutual\r
767      * dependencies. At least dependend (indepedent) groupings are in the list\r
768      * saved at first positions. For every grouping the record is added to map\r
769      * {@link BindingGeneratorImpl#allGroupings allGroupings}\r
770      * \r
771      * @param module\r
772      *            module from which is obtained set of all grouping objects to\r
773      *            iterate over them\r
774      * @return list of <code>Type</code> which are generated from groupings\r
775      *         (object of type <code>GroupingDefinition</code>)\r
776      * \r
777      */\r
778     private List<Type> allGroupingsToGenTypes(final Module module) {\r
779         if (module == null) {\r
780             throw new IllegalArgumentException("Module parameter can not be null");\r
781         }\r
782         final List<Type> genTypes = new ArrayList<>();\r
783         final String basePackageName = moduleNamespaceToPackageName(module);\r
784         final Set<GroupingDefinition> groupings = module.getGroupings();\r
785         List<GroupingDefinition> groupingsSortedByDependencies;\r
786 \r
787         groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings);\r
788 \r
789         for (final GroupingDefinition grouping : groupingsSortedByDependencies) {\r
790             GeneratedType genType = groupingToGenType(basePackageName, grouping);\r
791             genTypes.add(genType);\r
792             SchemaPath schemaPath = grouping.getPath();\r
793             allGroupings.put(schemaPath, genType);\r
794         }\r
795         return genTypes;\r
796     }\r
797 \r
798     /**\r
799      * Converts individual grouping to GeneratedType. Firstly generated type\r
800      * builder is created and every child node of grouping is resolved to the\r
801      * method.\r
802      * \r
803      * @param basePackageName\r
804      *            string containing name of package to which grouping belongs.\r
805      * @param grouping\r
806      *            GroupingDefinition which contains data about grouping\r
807      * @return GeneratedType which is generated from grouping (object of type\r
808      *         <code>GroupingDefinition</code>)\r
809      */\r
810     private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) {\r
811         if (grouping == null) {\r
812             return null;\r
813         }\r
814 \r
815         final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath());\r
816         final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();\r
817         final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping);\r
818 \r
819         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);\r
820         return typeBuilder.toInstance();\r
821     }\r
822 \r
823     /**\r
824      * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base\r
825      * type of <code>typeDefinition</code> is of the type ExtendedType then this\r
826      * method is recursivelly called with this base type.\r
827      * \r
828      * @param typeDefinition\r
829      *            TypeDefinition in which should be EnumTypeDefinition found as\r
830      *            base type\r
831      * @return EnumTypeDefinition if it is found inside\r
832      *         <code>typeDefinition</code> or <code>null</code> in other case\r
833      */\r
834     private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition<?> typeDefinition) {\r
835         if (typeDefinition != null) {\r
836             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {\r
837                 return (EnumTypeDefinition) typeDefinition.getBaseType();\r
838             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {\r
839                 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());\r
840             }\r
841         }\r
842         return null;\r
843     }\r
844 \r
845     /**\r
846      * Adds enumeration builder created from <code>enumTypeDef</code> to\r
847      * <code>typeBuilder</code>.\r
848      * \r
849      * Each <code>enumTypeDef</code> item is added to builder with its name and\r
850      * value.\r
851      * \r
852      * @param enumTypeDef\r
853      *            EnumTypeDefinition contains enum data\r
854      * @param enumName\r
855      *            string contains name which will be assigned to enumeration\r
856      *            builder\r
857      * @param typeBuilder\r
858      *            GeneratedTypeBuilder to which will be enum builder assigned\r
859      * @return enumeration builder which contais data from\r
860      *         <code>enumTypeDef</code>\r
861      */\r
862     private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,\r
863             final GeneratedTypeBuilder typeBuilder) {\r
864         if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)\r
865                 && (enumTypeDef.getQName().getLocalName() != null)) {\r
866 \r
867             final String enumerationName = parseToClassName(enumName);\r
868             final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);\r
869 \r
870             if (enumBuilder != null) {\r
871                 final List<EnumPair> enums = enumTypeDef.getValues();\r
872                 if (enums != null) {\r
873                     int listIndex = 0;\r
874                     for (final EnumPair enumPair : enums) {\r
875                         if (enumPair != null) {\r
876                             final String enumPairName = parseToClassName(enumPair.getName());\r
877                             Integer enumPairValue = enumPair.getValue();\r
878 \r
879                             if (enumPairValue == null) {\r
880                                 enumPairValue = listIndex;\r
881                             }\r
882                             enumBuilder.addValue(enumPairName, enumPairValue);\r
883                             listIndex++;\r
884                         }\r
885                     }\r
886                 }\r
887                 return enumBuilder;\r
888             }\r
889         }\r
890         return null;\r
891     }\r
892 \r
893     /**\r
894      * Generates type builder for <code>module</code>.\r
895      * \r
896      * @param module\r
897      *            Module which is source of package name for generated type\r
898      *            builder\r
899      * @param postfix\r
900      *            string which is added to the module class name representation\r
901      *            as suffix\r
902      * @return instance of GeneratedTypeBuilder which represents\r
903      *         <code>module</code>.\r
904      * @throws IllegalArgumentException\r
905      *             if <code>module</code> equals null\r
906      */\r
907     private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) {\r
908         if (module == null) {\r
909             throw new IllegalArgumentException("Module reference cannot be NULL!");\r
910         }\r
911         String packageName = moduleNamespaceToPackageName(module);\r
912         final String moduleName = parseToClassName(module.getName()) + postfix;\r
913 \r
914         return new GeneratedTypeBuilderImpl(packageName, moduleName);\r
915 \r
916     }\r
917 \r
918     /**\r
919      * Converts <code>augSchema</code> to list of <code>Type</code> which\r
920      * contains generated type for augmentation. In addition there are also\r
921      * generated types for all containers, list and choices which are child of\r
922      * <code>augSchema</code> node or a generated types for cases are added if\r
923      * augmented node is choice.\r
924      * \r
925      * @param augmentPackageName\r
926      *            string with the name of the package to which the augmentation\r
927      *            belongs\r
928      * @param augSchema\r
929      *            AugmentationSchema which is contains data about agumentation\r
930      *            (target path, childs...)\r
931      * @return list of <code>Type</code> objects which contains generated type\r
932      *         for augmentation and for container, list and choice child nodes\r
933      * @throws IllegalArgumentException\r
934      *             <ul>\r
935      *             <li>if <code>augmentPackageName</code> equals null</li>\r
936      *             <li>if <code>augSchema</code> equals null</li>\r
937      *             <li>if target path of <code>augSchema</code> equals null</li>\r
938      *             </ul>\r
939      */\r
940     private List<Type> augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) {\r
941         if (augmentPackageName == null) {\r
942             throw new IllegalArgumentException("Package Name cannot be NULL!");\r
943         }\r
944         if (augSchema == null) {\r
945             throw new IllegalArgumentException("Augmentation Schema cannot be NULL!");\r
946         }\r
947         if (augSchema.getTargetPath() == null) {\r
948             throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL).");\r
949         }\r
950 \r
951         final List<Type> genTypes = new ArrayList<>();\r
952 \r
953         // EVERY augmented interface will extends Augmentation<T> interface\r
954         // and DataObject interface!!!\r
955         final SchemaPath targetPath = augSchema.getTargetPath();\r
956         final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);\r
957         if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)\r
958                 && (targetSchemaNode.getQName().getLocalName() != null)) {\r
959             final Module targetModule = findParentModule(schemaContext, targetSchemaNode);\r
960             final String targetBasePackage = moduleNamespaceToPackageName(targetModule);\r
961             final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());\r
962             final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();\r
963             final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();\r
964 \r
965             if (!(targetSchemaNode instanceof ChoiceNode)) {\r
966                 final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,\r
967                         targetPackageName, targetSchemaNodeName, augSchema);\r
968                 final GeneratedType augType = augTypeBuilder.toInstance();\r
969                 genTypes.add(augType);\r
970             } else {\r
971                 final Type refChoiceType = new ReferencedTypeImpl(targetPackageName,\r
972                         parseToClassName(targetSchemaNodeName));\r
973                 final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode;\r
974                 final Set<ChoiceCaseNode> choiceCaseNodes = choiceTarget.getCases();\r
975                 genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType,\r
976                         choiceCaseNodes));\r
977             }\r
978             genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));\r
979         }\r
980         return genTypes;\r
981     }\r
982 \r
983     /**\r
984      * Returns a generated type builder for an augmentation.\r
985      * \r
986      * The name of the type builder is equal to the name of augmented node with\r
987      * serial number as suffix.\r
988      * \r
989      * @param augmentPackageName\r
990      *            string with contains the package name to which the augment\r
991      *            belongs\r
992      * @param targetPackageName\r
993      *            string with the package name to which the augmented node\r
994      *            belongs\r
995      * @param targetSchemaNodeName\r
996      *            string with the name of the augmented node\r
997      * @param augSchema\r
998      *            augmentation schema which contains data about the child nodes\r
999      *            and uses of augment\r
1000      * @return generated type builder for augment\r
1001      */\r
1002     private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName,\r
1003             final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) {\r
1004         final String targetTypeName = parseToClassName(targetSchemaNodeName);\r
1005         Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);\r
1006         if (augmentBuilders == null) {\r
1007             augmentBuilders = new HashMap<>();\r
1008             genTypeBuilders.put(augmentPackageName, augmentBuilders);\r
1009         }\r
1010         final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes());\r
1011         \r
1012         final String augTypeName =  augIdentifier != null ? parseToClassName(augIdentifier): augGenTypeName(augmentBuilders, targetTypeName);\r
1013         final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName);\r
1014         final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();\r
1015 \r
1016         final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);\r
1017 \r
1018         augTypeBuilder.addImplementsType(Types.DATA_OBJECT);\r
1019         augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));\r
1020         addImplementedInterfaceFromUses(augSchema, augTypeBuilder);\r
1021 \r
1022         augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes);\r
1023         augmentBuilders.put(augTypeName, augTypeBuilder);\r
1024         return augTypeBuilder;\r
1025     }\r
1026 \r
1027     private String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {\r
1028         String ret = null;\r
1029         for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) {\r
1030             QName nodeType = unknownSchemaNode.getNodeType();\r
1031             if(AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName()) &&\r
1032                     YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) {\r
1033                 return unknownSchemaNode.getNodeParameter();\r
1034             }\r
1035         }\r
1036         return ret;\r
1037     }\r
1038 \r
1039     /**\r
1040      * Convert a container, list and choice subnodes (and recursivelly their\r
1041      * subnodes) of augment to generated types\r
1042      * \r
1043      * @param augBasePackageName\r
1044      *            string with the augment package name\r
1045      * @param augChildNodes\r
1046      *            set of data schema nodes which represents child nodes of the\r
1047      *            augment\r
1048      * \r
1049      * @return list of <code>Type</code> which represents container, list and\r
1050      *         choice subnodes of augment\r
1051      */\r
1052     private List<Type> augmentationBodyToGenTypes(final String augBasePackageName,\r
1053             final Set<DataSchemaNode> augChildNodes) {\r
1054         final List<Type> genTypes = new ArrayList<>();\r
1055         final List<DataNodeIterator> augSchemaIts = new ArrayList<>();\r
1056         for (final DataSchemaNode childNode : augChildNodes) {\r
1057             if (childNode instanceof DataNodeContainer) {\r
1058                 augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode));\r
1059 \r
1060                 if (childNode instanceof ContainerSchemaNode) {\r
1061                     genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode));\r
1062                 } else if (childNode instanceof ListSchemaNode) {\r
1063                     genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));\r
1064                 }\r
1065             } else if (childNode instanceof ChoiceNode) {\r
1066                 final ChoiceNode choice = (ChoiceNode) childNode;\r
1067                 for (final ChoiceCaseNode caseNode : choice.getCases()) {\r
1068                     augSchemaIts.add(new DataNodeIterator(caseNode));\r
1069                 }\r
1070                 genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode));\r
1071             }\r
1072         }\r
1073 \r
1074         for (final DataNodeIterator it : augSchemaIts) {\r
1075             final List<ContainerSchemaNode> augContainers = it.allContainers();\r
1076             final List<ListSchemaNode> augLists = it.allLists();\r
1077             final List<ChoiceNode> augChoices = it.allChoices();\r
1078 \r
1079             if (augContainers != null) {\r
1080                 for (final ContainerSchemaNode container : augContainers) {\r
1081                     genTypes.add(containerToGenType(augBasePackageName, container));\r
1082                 }\r
1083             }\r
1084             if (augLists != null) {\r
1085                 for (final ListSchemaNode list : augLists) {\r
1086                     genTypes.addAll(listToGenType(augBasePackageName, list));\r
1087                 }\r
1088             }\r
1089             if (augChoices != null) {\r
1090                 for (final ChoiceNode choice : augChoices) {\r
1091                     genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice));\r
1092                 }\r
1093             }\r
1094         }\r
1095         return genTypes;\r
1096     }\r
1097 \r
1098     /**\r
1099      * Returns first unique name for the augment generated type builder. The\r
1100      * generated type builder name for augment consists from name of augmented\r
1101      * node and serial number of its augmentation.\r
1102      * \r
1103      * @param builders\r
1104      *            map of builders which were created in the package to which the\r
1105      *            augmentation belongs\r
1106      * @param genTypeName\r
1107      *            string with name of augmented node\r
1108      * @return string with unique name for augmentation builder\r
1109      */\r
1110     private String augGenTypeName(final Map<String, GeneratedTypeBuilder> builders, final String genTypeName) {\r
1111         String augTypeName = genTypeName;\r
1112 \r
1113         int index = 1;\r
1114         while ((builders != null) && builders.containsKey(genTypeName + index)) {\r
1115             index++;\r
1116         }\r
1117         augTypeName += index;\r
1118         return augTypeName;\r
1119     }\r
1120 \r
1121     /**\r
1122      * Converts <code>containerNode</code> to generated type. Firstly the\r
1123      * generated type builder is created. The subnodes of\r
1124      * <code>containerNode</code> are added as methods and the instance of\r
1125      * <code>GeneratedType</code> is returned.\r
1126      * \r
1127      * @param basePackageName\r
1128      *            string with name of the package to which the superior node\r
1129      *            belongs\r
1130      * @param containerNode\r
1131      *            container schema node with the data about childs nodes and\r
1132      *            schema paths\r
1133      * @return generated type for <code>containerNode</code>\r
1134      */\r
1135     private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) {\r
1136         if (containerNode == null) {\r
1137             return null;\r
1138         }\r
1139 \r
1140         final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());\r
1141         final Set<DataSchemaNode> schemaNodes = containerNode.getChildNodes();\r
1142         final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode);\r
1143 \r
1144         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);\r
1145         return typeBuilder.toInstance();\r
1146     }\r
1147 \r
1148     /**\r
1149      * \r
1150      * @param basePackageName\r
1151      * @param typeBuilder\r
1152      * @param schemaNodes\r
1153      * @return\r
1154      */\r
1155     private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName,\r
1156             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {\r
1157         if ((schemaNodes != null) && (typeBuilder != null)) {\r
1158             for (final DataSchemaNode schemaNode : schemaNodes) {\r
1159                 if (schemaNode.isAugmenting() || schemaNode.isAddedByUses()) {\r
1160                     continue;\r
1161                 }\r
1162                 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);\r
1163             }\r
1164         }\r
1165         return typeBuilder;\r
1166     }\r
1167 \r
1168     private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName,\r
1169             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {\r
1170         if ((schemaNodes != null) && (typeBuilder != null)) {\r
1171             for (final DataSchemaNode schemaNode : schemaNodes) {\r
1172                 if (schemaNode.isAugmenting()) {\r
1173                     addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);\r
1174                 }\r
1175             }\r
1176         }\r
1177         return typeBuilder;\r
1178     }\r
1179 \r
1180     private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode,\r
1181             final GeneratedTypeBuilder typeBuilder) {\r
1182         if (schemaNode != null && typeBuilder != null) {\r
1183             if (schemaNode instanceof LeafSchemaNode) {\r
1184                 resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode);\r
1185             } else if (schemaNode instanceof LeafListSchemaNode) {\r
1186                 resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);\r
1187             } else if (schemaNode instanceof ContainerSchemaNode) {\r
1188                 resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);\r
1189             } else if (schemaNode instanceof ListSchemaNode) {\r
1190                 resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);\r
1191             } else if (schemaNode instanceof ChoiceNode) {\r
1192                 resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode);\r
1193             }\r
1194         }\r
1195     }\r
1196 \r
1197     private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,\r
1198             final ChoiceNode choiceNode) {\r
1199         if (basePackageName == null) {\r
1200             throw new IllegalArgumentException("Base Package Name cannot be NULL!");\r
1201         }\r
1202         if (typeBuilder == null) {\r
1203             throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");\r
1204         }\r
1205         if (choiceNode == null) {\r
1206             throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");\r
1207         }\r
1208 \r
1209         final String choiceName = choiceNode.getQName().getLocalName();\r
1210         if (choiceName != null && !choiceNode.isAddedByUses()) {\r
1211             final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());\r
1212             final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);\r
1213             constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType);\r
1214         }\r
1215     }\r
1216 \r
1217     private List<GeneratedType> choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) {\r
1218         if (basePackageName == null) {\r
1219             throw new IllegalArgumentException("Base Package Name cannot be NULL!");\r
1220         }\r
1221         if (choiceNode == null) {\r
1222             throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");\r
1223         }\r
1224 \r
1225         final List<GeneratedType> generatedTypes = new ArrayList<>();\r
1226         final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());\r
1227         final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);\r
1228         choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT);\r
1229         final GeneratedType choiceType = choiceTypeBuilder.toInstance();\r
1230 \r
1231         generatedTypes.add(choiceType);\r
1232         final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();\r
1233         if ((caseNodes != null) && !caseNodes.isEmpty()) {\r
1234             generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes));\r
1235         }\r
1236         return generatedTypes;\r
1237     }\r
1238 \r
1239     private List<GeneratedType> generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType,\r
1240             final Set<ChoiceCaseNode> caseNodes) {\r
1241         if (basePackageName == null) {\r
1242             throw new IllegalArgumentException("Base Package Name cannot be NULL!");\r
1243         }\r
1244         if (refChoiceType == null) {\r
1245             throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");\r
1246         }\r
1247         if (caseNodes == null) {\r
1248             throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");\r
1249         }\r
1250 \r
1251         final List<GeneratedType> generatedTypes = new ArrayList<>();\r
1252         for (final ChoiceCaseNode caseNode : caseNodes) {\r
1253             if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) {\r
1254                 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());\r
1255                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);\r
1256                 caseTypeBuilder.addImplementsType(refChoiceType);\r
1257 \r
1258                 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();\r
1259                 if (childNodes != null) {\r
1260                     resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);\r
1261                 }\r
1262                 generatedTypes.add(caseTypeBuilder.toInstance());\r
1263             }\r
1264         }\r
1265 \r
1266         return generatedTypes;\r
1267     }\r
1268 \r
1269     /**\r
1270      * Generates list of generated types for all the cases of a choice which are\r
1271      * added to the choice through the augment.\r
1272      * \r
1273      * \r
1274      * @param basePackageName\r
1275      *            string contains name of package to which augment belongs. If\r
1276      *            an augmented choice is from an other package (pcg1) than an\r
1277      *            augmenting choice (pcg2) then case's of the augmenting choice\r
1278      *            will belong to pcg2.\r
1279      * @param refChoiceType\r
1280      *            Type which represents the choice to which case belongs. Every\r
1281      *            case has to contain its choice in extend part.\r
1282      * @param caseNodes\r
1283      *            set of choice case nodes for which is checked if are/aren't\r
1284      *            added to choice through augmentation\r
1285      * @return list of generated types which represents augmented cases of\r
1286      *         choice <code>refChoiceType</code>\r
1287      * @throws IllegalArgumentException\r
1288      *             <ul>\r
1289      *             <li>if <code>basePackageName</code> equals null</li>\r
1290      *             <li>if <code>refChoiceType</code> equals null</li>\r
1291      *             <li>if <code>caseNodes</code> equals null</li>\r
1292      *             </ul>\r
1293      */\r
1294     private List<GeneratedType> generateTypesFromAugmentedChoiceCases(final String basePackageName,\r
1295             final Type refChoiceType, final Set<ChoiceCaseNode> caseNodes) {\r
1296         if (basePackageName == null) {\r
1297             throw new IllegalArgumentException("Base Package Name cannot be NULL!");\r
1298         }\r
1299         if (refChoiceType == null) {\r
1300             throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");\r
1301         }\r
1302         if (caseNodes == null) {\r
1303             throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");\r
1304         }\r
1305 \r
1306         final List<GeneratedType> generatedTypes = new ArrayList<>();\r
1307         for (final ChoiceCaseNode caseNode : caseNodes) {\r
1308             if (caseNode != null && caseNode.isAugmenting()) {\r
1309                 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());\r
1310                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);\r
1311                 caseTypeBuilder.addImplementsType(refChoiceType);\r
1312 \r
1313                 final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();\r
1314                 if (childNodes != null) {\r
1315                     resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);\r
1316                 }\r
1317                 generatedTypes.add(caseTypeBuilder.toInstance());\r
1318             }\r
1319         }\r
1320 \r
1321         return generatedTypes;\r
1322     }\r
1323 \r
1324     private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {\r
1325         if ((leaf != null) && (typeBuilder != null)) {\r
1326             final String leafName = leaf.getQName().getLocalName();\r
1327             String leafDesc = leaf.getDescription();\r
1328             if (leafDesc == null) {\r
1329                 leafDesc = "";\r
1330             }\r
1331 \r
1332             if (leafName != null && !leaf.isAddedByUses()) {\r
1333                 final TypeDefinition<?> typeDef = leaf.getType();\r
1334 \r
1335                 Type returnType = null;\r
1336                 if (typeDef instanceof EnumTypeDefinition) {\r
1337                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);\r
1338                     final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);\r
1339                     final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName,\r
1340                             typeBuilder);\r
1341 \r
1342                     if (enumBuilder != null) {\r
1343                         returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());\r
1344                     }\r
1345                     ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);\r
1346                 } else if (typeDef instanceof UnionType) {\r
1347                     GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);\r
1348                     if (genTOBuilder != null) {\r
1349                         returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());\r
1350                     }\r
1351                 } else if (typeDef instanceof BitsTypeDefinition) {\r
1352                     GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);\r
1353                     if (genTOBuilder != null) {\r
1354                         returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());\r
1355                     }\r
1356                 } else {\r
1357                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);\r
1358                 }\r
1359                 if (returnType != null) {\r
1360                     constructGetter(typeBuilder, leafName, leafDesc, returnType);\r
1361                     return true;\r
1362                 }\r
1363             }\r
1364         }\r
1365         return false;\r
1366     }\r
1367 \r
1368     private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,\r
1369             boolean isReadOnly) {\r
1370         if ((leaf != null) && (toBuilder != null)) {\r
1371             final String leafName = leaf.getQName().getLocalName();\r
1372             String leafDesc = leaf.getDescription();\r
1373             if (leafDesc == null) {\r
1374                 leafDesc = "";\r
1375             }\r
1376 \r
1377             if (leafName != null && !leaf.isAddedByUses()) {\r
1378                 final TypeDefinition<?> typeDef = leaf.getType();\r
1379 \r
1380                 // TODO: properly resolve enum types\r
1381                 final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);\r
1382 \r
1383                 if (returnType != null) {\r
1384                     final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName));\r
1385 \r
1386                     propBuilder.setReadOnly(isReadOnly);\r
1387                     propBuilder.setReturnType(returnType);\r
1388                     propBuilder.setComment(leafDesc);\r
1389 \r
1390                     toBuilder.addEqualsIdentity(propBuilder);\r
1391                     toBuilder.addHashIdentity(propBuilder);\r
1392                     toBuilder.addToStringProperty(propBuilder);\r
1393 \r
1394                     return true;\r
1395                 }\r
1396             }\r
1397         }\r
1398         return false;\r
1399     }\r
1400 \r
1401     private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {\r
1402         if ((node != null) && (typeBuilder != null)) {\r
1403             final String nodeName = node.getQName().getLocalName();\r
1404             String nodeDesc = node.getDescription();\r
1405             if (nodeDesc == null) {\r
1406                 nodeDesc = "";\r
1407             }\r
1408 \r
1409             if (nodeName != null && !node.isAddedByUses()) {\r
1410                 final TypeDefinition<?> type = node.getType();\r
1411                 final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type));\r
1412 \r
1413                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);\r
1414                 return true;\r
1415             }\r
1416         }\r
1417         return false;\r
1418     }\r
1419 \r
1420     private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,\r
1421             final ContainerSchemaNode containerNode) {\r
1422         if ((containerNode != null) && (typeBuilder != null)) {\r
1423             final String nodeName = containerNode.getQName().getLocalName();\r
1424 \r
1425             if (nodeName != null && !containerNode.isAddedByUses()) {\r
1426                 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());\r
1427 \r
1428                 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);\r
1429                 constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType);\r
1430 \r
1431                 return true;\r
1432             }\r
1433         }\r
1434         return false;\r
1435     }\r
1436 \r
1437     private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,\r
1438             final ListSchemaNode schemaNode) {\r
1439         if ((schemaNode != null) && (typeBuilder != null)) {\r
1440             final String listName = schemaNode.getQName().getLocalName();\r
1441 \r
1442             if (listName != null && !schemaNode.isAddedByUses()) {\r
1443                 final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());\r
1444                 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);\r
1445                 constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));\r
1446                 return true;\r
1447             }\r
1448         }\r
1449         return false;\r
1450     }\r
1451 \r
1452     /**\r
1453      * Method instantiates new Generated Type Builder and sets the implements\r
1454      * definitions of Data Object and Augmentable.\r
1455      * \r
1456      * @param packageName\r
1457      *            Generated Type Package Name\r
1458      * @param schemaNode\r
1459      *            Schema Node definition\r
1460      * @return Generated Type Builder instance for Schema Node definition\r
1461      */\r
1462     private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {\r
1463         final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");\r
1464         builder.addImplementsType(Types.DATA_OBJECT);\r
1465         if (!(schemaNode instanceof GroupingDefinition)) {\r
1466             builder.addImplementsType(Types.augmentableTypeFor(builder));\r
1467         }\r
1468 \r
1469         if (schemaNode instanceof DataNodeContainer) {\r
1470             addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder);\r
1471         }\r
1472 \r
1473         return builder;\r
1474     }\r
1475 \r
1476     /**\r
1477      * \r
1478      * @param packageName\r
1479      * @param schemaNode\r
1480      * @return\r
1481      */\r
1482     private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {\r
1483         return addRawInterfaceDefinition(packageName, schemaNode, "");\r
1484     }\r
1485 \r
1486     private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,\r
1487             final String prefix) {\r
1488         if (schemaNode == null) {\r
1489             throw new IllegalArgumentException("Data Schema Node cannot be NULL!");\r
1490         }\r
1491         if (packageName == null) {\r
1492             throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");\r
1493         }\r
1494         if (schemaNode.getQName() == null) {\r
1495             throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!");\r
1496         }\r
1497         final String schemaNodeName = schemaNode.getQName().getLocalName();\r
1498         if (schemaNodeName == null) {\r
1499             throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!");\r
1500         }\r
1501 \r
1502         final String genTypeName;\r
1503         if (prefix == null) {\r
1504             genTypeName = parseToClassName(schemaNodeName);\r
1505         } else {\r
1506             genTypeName = prefix + parseToClassName(schemaNodeName);\r
1507         }\r
1508 \r
1509         final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);\r
1510         if (!genTypeBuilders.containsKey(packageName)) {\r
1511             final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();\r
1512             builders.put(genTypeName, newType);\r
1513             genTypeBuilders.put(packageName, builders);\r
1514         } else {\r
1515             final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);\r
1516             if (!builders.containsKey(genTypeName)) {\r
1517                 builders.put(genTypeName, newType);\r
1518             }\r
1519         }\r
1520         return newType;\r
1521     }\r
1522 \r
1523     private String getterMethodName(final String methodName) {\r
1524         final StringBuilder method = new StringBuilder();\r
1525         method.append("get");\r
1526         method.append(parseToClassName(methodName));\r
1527         return method.toString();\r
1528     }\r
1529 \r
1530     private String setterMethodName(final String methodName) {\r
1531         final StringBuilder method = new StringBuilder();\r
1532         method.append("set");\r
1533         method.append(parseToClassName(methodName));\r
1534         return method.toString();\r
1535     }\r
1536 \r
1537     private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,\r
1538             final String schemaNodeName, final String comment, final Type returnType) {\r
1539         final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName));\r
1540 \r
1541         getMethod.setComment(comment);\r
1542         getMethod.setReturnType(returnType);\r
1543 \r
1544         return getMethod;\r
1545     }\r
1546 \r
1547     private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder,\r
1548             final String schemaNodeName, final String comment, final Type parameterType) {\r
1549         final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName));\r
1550 \r
1551         setMethod.setComment(comment);\r
1552         setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName));\r
1553         setMethod.setReturnType(Types.voidType());\r
1554 \r
1555         return setMethod;\r
1556     }\r
1557 \r
1558     private List<Type> listToGenType(final String basePackageName, final ListSchemaNode list) {\r
1559         if (basePackageName == null) {\r
1560             throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");\r
1561         }\r
1562         if (list == null) {\r
1563             throw new IllegalArgumentException("List Schema Node cannot be NULL!");\r
1564         }\r
1565 \r
1566         final String packageName = packageNameForGeneratedType(basePackageName, list.getPath());\r
1567         final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list);\r
1568         final List<String> listKeys = listKeys(list);\r
1569         GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys);\r
1570         \r
1571         \r
1572         if(genTOBuilder != null) {\r
1573             ParameterizedType identifierMarker = Types.parameterizedTypeFor( Types.typeForClass(Identifier.class), typeBuilder);\r
1574             ParameterizedType identifiableMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class), genTOBuilder);\r
1575             genTOBuilder.addImplementsType(identifierMarker);\r
1576             typeBuilder.addImplementsType(identifiableMarker);\r
1577         }\r
1578         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();\r
1579 \r
1580         for (final DataSchemaNode schemaNode : schemaNodes) {\r
1581             if (schemaNode.isAugmenting()) {\r
1582                 continue;\r
1583             }\r
1584             addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys);\r
1585         }\r
1586         return typeBuildersToGenTypes(typeBuilder, genTOBuilder);\r
1587     }\r
1588 \r
1589     private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode,\r
1590             final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {\r
1591         if (schemaNode == null) {\r
1592             throw new IllegalArgumentException("Data Schema Node cannot be NULL!");\r
1593         }\r
1594 \r
1595         if (typeBuilder == null) {\r
1596             throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");\r
1597         }\r
1598 \r
1599         if (schemaNode instanceof LeafSchemaNode) {\r
1600             final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;\r
1601             if (!isPartOfListKey(leaf, listKeys)) {\r
1602                 resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);\r
1603             } else {\r
1604                 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);\r
1605             }\r
1606         } else if (schemaNode instanceof LeafListSchemaNode) {\r
1607             resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);\r
1608         } else if (schemaNode instanceof ContainerSchemaNode) {\r
1609             resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);\r
1610         } else if (schemaNode instanceof ListSchemaNode) {\r
1611             resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);\r
1612         }\r
1613     }\r
1614 \r
1615     private List<Type> typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {\r
1616         final List<Type> genTypes = new ArrayList<>();\r
1617         if (typeBuilder == null) {\r
1618             throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");\r
1619         }\r
1620 \r
1621         if (genTOBuilder != null) {\r
1622             final GeneratedTransferObject genTO = genTOBuilder.toInstance();\r
1623             constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO);\r
1624             genTypes.add(genTO);\r
1625         }\r
1626         genTypes.add(typeBuilder.toInstance());\r
1627         return genTypes;\r
1628     }\r
1629 \r
1630     /**\r
1631      * @param list\r
1632      * @return\r
1633      */\r
1634     private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) {\r
1635         final String listName = list.getQName().getLocalName() + "Key";\r
1636         return schemaNodeToTransferObjectBuilder(packageName, list, listName);\r
1637     }\r
1638 \r
1639     private boolean isPartOfListKey(final LeafSchemaNode leaf, final List<String> keys) {\r
1640         if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {\r
1641             final String leafName = leaf.getQName().getLocalName();\r
1642             if (keys.contains(leafName)) {\r
1643                 return true;\r
1644             }\r
1645         }\r
1646         return false;\r
1647     }\r
1648 \r
1649     private List<String> listKeys(final ListSchemaNode list) {\r
1650         final List<String> listKeys = new ArrayList<>();\r
1651 \r
1652         if (list.getKeyDefinition() != null) {\r
1653             final List<QName> keyDefinitions = list.getKeyDefinition();\r
1654 \r
1655             for (final QName keyDefinition : keyDefinitions) {\r
1656                 listKeys.add(keyDefinition.getLocalName());\r
1657             }\r
1658         }\r
1659         return listKeys;\r
1660     }\r
1661 \r
1662     private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) {\r
1663         if (packageName == null) {\r
1664             throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");\r
1665         }\r
1666         if (list == null) {\r
1667             throw new IllegalArgumentException("List Schema Node cannot be NULL!");\r
1668         }\r
1669 \r
1670         final String schemaNodeName = list.getQName().getLocalName();\r
1671         final String genTypeName = parseToClassName(schemaNodeName);\r
1672 \r
1673         GeneratedTypeBuilder typeBuilder = null;\r
1674         final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);\r
1675         if (builders != null) {\r
1676             typeBuilder = builders.get(genTypeName);\r
1677         }\r
1678         if (typeBuilder == null) {\r
1679             typeBuilder = addDefaultInterfaceDefinition(packageName, list);\r
1680         }\r
1681         return typeBuilder;\r
1682     }\r
1683 \r
1684     private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list,\r
1685             final List<String> listKeys) {\r
1686         GeneratedTOBuilder genTOBuilder = null;\r
1687         if (listKeys.size() > 0) {\r
1688             genTOBuilder = resolveListKey(packageName, list);\r
1689         }\r
1690         return genTOBuilder;\r
1691     }\r
1692 \r
1693     private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,\r
1694             String leafName) {\r
1695         String className = parseToClassName(leafName);\r
1696         GeneratedTOBuilder genTOBuilder = null;\r
1697         if (typeDef instanceof UnionType) {\r
1698             genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition(\r
1699                     typeBuilder.getFullyQualifiedName(), typeDef, className);\r
1700         } else if (typeDef instanceof BitsTypeDefinition) {\r
1701             genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(\r
1702                     typeBuilder.getFullyQualifiedName(), typeDef, className);\r
1703         }\r
1704         if (genTOBuilder != null) {\r
1705             typeBuilder.addEnclosingTransferObject(genTOBuilder);\r
1706             return genTOBuilder;\r
1707         }\r
1708         return null;\r
1709 \r
1710     }\r
1711 \r
1712     /**\r
1713      * Adds the implemented types to type builder. The method passes through the\r
1714      * list of elements which contains {@code dataNodeContainer} and adds them\r
1715      * as <i>implements type</i> to <code>builder</code>\r
1716      * \r
1717      * @param dataNodeContainer\r
1718      *            element which contains the list of used YANG groupings\r
1719      * @param builder\r
1720      *            builder to which are added implemented types according to\r
1721      *            <code>dataNodeContainer</code>\r
1722      * @return generated type builder which contains implemented types\r
1723      */\r
1724     private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer,\r
1725             final GeneratedTypeBuilder builder) {\r
1726         for (UsesNode usesNode : dataNodeContainer.getUses()) {\r
1727             if (usesNode.getGroupingPath() != null) {\r
1728                 GeneratedType genType = allGroupings.get(usesNode.getGroupingPath());\r
1729                 if (genType == null) {\r
1730                     throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for "\r
1731                             + builder.getName());\r
1732                 }\r
1733                 builder.addImplementsType(genType);\r
1734             }\r
1735         }\r
1736         return builder;\r
1737     }\r
1738 \r
1739 }\r