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