Bug fix for ForwardingRulesManager:
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / generator / impl / BindingGeneratorImpl.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.binding.generator.impl;
9
10 import java.net.URI;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Calendar;
14 import java.util.GregorianCalendar;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil;
22 import org.opendaylight.controller.binding.generator.util.Types;
23 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
24 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
25 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
26 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
27 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
28 import org.opendaylight.controller.sal.binding.model.api.Type;
29 import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
30 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
31 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
32 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
33 import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;
34 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
35 import org.opendaylight.controller.yang.common.QName;
36 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
37 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
38 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
39 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
40 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
41 import org.opendaylight.controller.yang.model.api.Module;
42 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
43 import org.opendaylight.controller.yang.model.api.RpcDefinition;
44 import org.opendaylight.controller.yang.model.api.SchemaContext;
45 import org.opendaylight.controller.yang.model.api.SchemaPath;
46 import org.opendaylight.controller.yang.model.api.TypeDefinition;
47 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
48 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
49 import org.opendaylight.controller.yang.model.util.DataNodeIterator;
50 import org.opendaylight.controller.yang.model.util.ExtendedType;
51
52 public class BindingGeneratorImpl implements BindingGenerator {
53
54     private static final String[] SET_VALUES = new String[] { "abstract",
55             "assert", "boolean", "break", "byte", "case", "catch", "char",
56             "class", "const", "continue", "default", "double", "do", "else",
57             "enum", "extends", "false", "final", "finally", "float", "for",
58             "goto", "if", "implements", "import", "instanceof", "int",
59             "interface", "long", "native", "new", "null", "package", "private",
60             "protected", "public", "return", "short", "static", "strictfp",
61             "super", "switch", "synchronized", "this", "throw", "throws",
62             "transient", "true", "try", "void", "volatile", "while" };
63
64     public static final Set<String> JAVA_RESERVED_WORDS = new HashSet<String>(
65             Arrays.asList(SET_VALUES));
66
67     private static Calendar calendar = new GregorianCalendar();
68     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
69     private TypeProvider typeProvider;
70     private String basePackageName;
71
72     public BindingGeneratorImpl() {
73         super();
74     }
75
76     private static String validatePackage(final String packageName) {
77         if (packageName != null) {
78             final String[] packNameParts = packageName.split("\\.");
79             if (packNameParts != null) {
80                 final StringBuilder builder = new StringBuilder();
81                 for (int i = 0; i < packNameParts.length; ++i) {
82                     if (JAVA_RESERVED_WORDS.contains(packNameParts[i])) {
83                         packNameParts[i] = "_" + packNameParts[i];
84                     }
85                     if (i > 0) {
86                         builder.append(".");
87                     }
88                     builder.append(packNameParts[i]);
89                 }
90                 return builder.toString();
91             }
92         }
93         return packageName;
94     }
95
96     @Override
97     public List<Type> generateTypes(final SchemaContext context) {
98         final List<Type> genTypes = new ArrayList<Type>();
99
100         if (context != null) {
101             typeProvider = new TypeProviderImpl(context);
102             final Set<Module> modules = context.getModules();
103             
104             if (modules != null) {
105                 for (final Module module : modules) {
106                     final DataNodeIterator moduleIterator = new DataNodeIterator(
107                             module);
108
109                     genTypeBuilders = new HashMap<String, Map<String, GeneratedTypeBuilder>>();
110                     final List<ContainerSchemaNode> schemaContainers = moduleIterator
111                             .allContainers();
112                     final List<ListSchemaNode> schemaLists = moduleIterator
113                             .allLists();
114
115                     basePackageName = BindingGeneratorUtil
116                             .moduleNamespaceToPackageName(
117                                     module.getNamespace(),
118                                     module.getYangVersion());
119
120                     if (schemaContainers.size() > 0) {
121                         for (final ContainerSchemaNode container : schemaContainers) {
122                             genTypes.add(containerToGenType(container));
123                         }
124                     }
125                     if (schemaLists.size() > 0) {
126                         for (final ListSchemaNode list : schemaLists) {
127                             genTypes.addAll(listToGenType(list));
128                         }
129                     }
130
131                     final GeneratedType genDataType = moduleToDataType(module);
132                     final GeneratedType genRpcType = rpcMethodsToGenType(module);
133                     final GeneratedType genNotifyType = notifycationsToGenType(module);
134
135                     if (genDataType != null) {
136                         genTypes.add(genDataType);
137                     }
138                     if (genRpcType != null) {
139                         genTypes.add(genRpcType);
140                     }
141                     if (genNotifyType != null) {
142                         genTypes.add(genNotifyType);
143                     }
144                 }
145                 
146                 //FIXME this is quick add of typedefs to generated types from type provider
147                 genTypes.addAll(((TypeProviderImpl)typeProvider).getGeneratedTypeDefs());
148             }
149         }
150         return genTypes;
151     }
152
153     private GeneratedType moduleToDataType(final Module module) {
154         if (module != null) {
155             final Set<TypeDefinition<?>> typeDefinitions = module
156                     .getTypeDefinitions();
157             final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(
158                     module, "Data");
159
160             if (moduleDataTypeBuilder != null) {
161                 if (typeDefinitions != null) {
162                     for (final TypeDefinition<?> typedef : typeDefinitions) {
163                         if (isDerivedFromEnumerationType(typedef)) {
164                             final EnumTypeDefinition enumBaseType = enumTypeDefFromExtendedType(typedef);
165                             resolveEnumFromTypeDefinition(enumBaseType, typedef
166                                     .getQName().getLocalName(),
167                                     moduleDataTypeBuilder);
168                         }
169                     }
170                 }
171
172                 final Set<DataSchemaNode> dataNodes = module.getChildNodes();
173                 resolveTypesFromDataSchemaNode(moduleDataTypeBuilder, dataNodes);
174                 return moduleDataTypeBuilder.toInstance();
175             }
176         }
177         return null;
178     }
179
180     private boolean isDerivedFromEnumerationType(
181             final TypeDefinition<?> typeDefinition) {
182         if (typeDefinition != null) {
183             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
184                 return true;
185             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
186                 return isDerivedFromEnumerationType(typeDefinition
187                         .getBaseType());
188             }
189         }
190         return false;
191     }
192
193     private EnumTypeDefinition enumTypeDefFromExtendedType(
194             final TypeDefinition<?> typeDefinition) {
195         if (typeDefinition != null) {
196             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
197                 return (EnumTypeDefinition) typeDefinition.getBaseType();
198             } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
199                 return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
200             }
201         }
202         return null;
203     }
204
205     private EnumBuilder resolveEnumFromTypeDefinition(
206             final EnumTypeDefinition enumTypeDef, final String enumName,
207             final GeneratedTypeBuilder typeBuilder) {
208         if ((enumTypeDef != null) && (typeBuilder != null)
209                 && (enumTypeDef.getQName() != null)
210                 && (enumTypeDef.getQName().getLocalName() != null)) {
211
212             final String enumerationName = BindingGeneratorUtil
213                     .parseToClassName(enumName);
214             final EnumBuilder enumBuilder = typeBuilder
215                     .addEnumeration(enumerationName);
216
217             if (enumBuilder != null) {
218                 final List<EnumPair> enums = enumTypeDef.getValues();
219                 if (enums != null) {
220                     int listIndex = 0;
221                     for (final EnumPair enumPair : enums) {
222                         if (enumPair != null) {
223                             final String enumPairName = BindingGeneratorUtil
224                                     .parseToClassName(enumPair.getName());
225                             Integer enumPairValue = enumPair.getValue();
226
227                             if (enumPairValue == null) {
228                                 enumPairValue = listIndex;
229                             }
230                             enumBuilder.addValue(enumPairName, enumPairValue);
231                             listIndex++;
232                         }
233                     }
234                 }
235                 return enumBuilder;
236             }
237         }
238         return null;
239     }
240
241     private GeneratedTypeBuilder moduleTypeBuilder(final Module module,
242             final String postfix) {
243         if (module != null) {
244             String packageName = resolveBasePackageName(module.getNamespace(),
245                     module.getYangVersion());
246             final String moduleName = BindingGeneratorUtil
247                     .parseToClassName(module.getName()) + postfix;
248
249             if (packageName != null) {
250                 packageName = validatePackage(packageName);
251                 return new GeneratedTypeBuilderImpl(packageName, moduleName);
252             }
253         }
254         return null;
255     }
256
257     private GeneratedType rpcMethodsToGenType(final Module module) {
258         if (module != null) {
259             final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
260             //TODO: add implementation
261             if ((rpcDefinitions != null) && !rpcDefinitions.isEmpty()) {
262                 final GeneratedTypeBuilder rpcTypeBuilder = moduleTypeBuilder(
263                         module, "Rpc");
264
265                 for (final RpcDefinition rpc : rpcDefinitions) {
266                     if (rpc != null) {
267
268                     }
269                 }
270             }
271         }
272         return null;
273     }
274
275     private GeneratedType notifycationsToGenType(final Module module) {
276         if (module != null) {
277             final Set<NotificationDefinition> notifications = module
278                     .getNotifications();
279             //TODO: add implementation
280             if ((notifications != null) && !notifications.isEmpty()) {
281                 final GeneratedTypeBuilder notifyTypeBuilder = moduleTypeBuilder(
282                         module, "Notification");
283
284                 for (final NotificationDefinition notification : notifications) {
285                     if (notification != null) {
286
287                     }
288                 }
289             }
290         }
291         return null;
292     }
293
294     // private String resolveGeneratedTypePackageName(final SchemaPath
295     // schemaPath) {
296     // final StringBuilder builder = new StringBuilder();
297     // builder.append(basePackageName);
298     // if ((schemaPath != null) && (schemaPath.getPath() != null)) {
299     // final List<QName> pathToNode = schemaPath.getPath();
300     // final int traversalSteps = (pathToNode.size() - 1);
301     // for (int i = 0; i < traversalSteps; ++i) {
302     // builder.append(".");
303     // String nodeLocalName = pathToNode.get(i).getLocalName();
304     //
305     // // TODO: refactor with use of BindingGeneratorUtil class
306     // nodeLocalName = nodeLocalName.replace(":", ".");
307     // nodeLocalName = nodeLocalName.replace("-", ".");
308     // builder.append(nodeLocalName);
309     // }
310     // return validatePackage(builder.toString());
311     // }
312     // return null;
313     // }
314
315     private GeneratedType containerToGenType(ContainerSchemaNode container) {
316         if (container == null) {
317             return null;
318         }
319         final Set<DataSchemaNode> schemaNodes = container.getChildNodes();
320         final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(container);
321
322         resolveTypesFromDataSchemaNode(typeBuilder, schemaNodes);
323         return typeBuilder.toInstance();
324     }
325
326     private GeneratedTypeBuilder resolveTypesFromDataSchemaNode(
327             final GeneratedTypeBuilder typeBuilder,
328             final Set<DataSchemaNode> schemaNodes) {
329
330         if ((schemaNodes != null) && (typeBuilder != null)) {
331             for (final DataSchemaNode node : schemaNodes) {
332                 if (node instanceof LeafSchemaNode) {
333                     resolveLeafSchemaNodeAsMethod(typeBuilder,
334                             (LeafSchemaNode) node);
335                 } else if (node instanceof LeafListSchemaNode) {
336                     resolveLeafListSchemaNode(typeBuilder,
337                             (LeafListSchemaNode) node);
338
339                 } else if (node instanceof ContainerSchemaNode) {
340                     resolveContainerSchemaNode(typeBuilder,
341                             (ContainerSchemaNode) node);
342                 } else if (node instanceof ListSchemaNode) {
343                     resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
344                 }
345             }
346         }
347         return typeBuilder;
348     }
349
350     private boolean resolveLeafSchemaNodeAsMethod(
351             final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
352         if ((leaf != null) && (typeBuilder != null)) {
353             final String leafName = leaf.getQName().getLocalName();
354             String leafDesc = leaf.getDescription();
355             if (leafDesc == null) {
356                 leafDesc = "";
357             }
358
359             if (leafName != null) {
360                 final TypeDefinition<?> typeDef = leaf.getType();
361
362                 Type type = null;
363                 if (!(typeDef instanceof EnumTypeDefinition)
364                         && !isDerivedFromEnumerationType(typeDef)) {
365                     type = typeProvider
366                             .javaTypeForSchemaDefinitionType(typeDef);
367                 } else {
368                     if (isImported(leaf.getPath(), typeDef.getPath())) {
369                         // TODO: resolving of imported enums as references to
370                         // GeneratedTypeData interface
371                     } else {
372                         final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
373                         final EnumBuilder enumBuilder = resolveEnumFromTypeDefinition(
374                                 enumTypeDef, leafName, typeBuilder);
375
376                         if (enumBuilder != null) {
377                             type = new ReferencedTypeImpl(
378                                     enumBuilder.getPackageName(),
379                                     enumBuilder.getName());
380                         }
381                     }
382                 }
383
384                 constructGetter(typeBuilder, leafName, leafDesc, type);
385                 if (!leaf.isConfiguration()) {
386                     constructSetter(typeBuilder, leafName, leafDesc, type);
387                 }
388                 return true;
389             }
390         }
391         return false;
392     }
393
394     private boolean isImported(final SchemaPath leafPath,
395             final SchemaPath typeDefPath) {
396         if ((leafPath != null) && (leafPath.getPath() != null)
397                 && (typeDefPath != null) && (typeDefPath.getPath() != null)) {
398
399             final QName leafPathQName = leafPath.getPath().get(0);
400             final QName typePathQName = typeDefPath.getPath().get(0);
401
402             if ((leafPathQName != null)
403                     && (leafPathQName.getNamespace() != null)
404                     && (typePathQName != null)
405                     && (typePathQName.getNamespace() != null)) {
406
407                 return !leafPathQName.getNamespace().equals(
408                         typePathQName.getNamespace());
409             }
410         }
411         return false;
412     }
413
414     private boolean resolveLeafSchemaNodeAsProperty(
415             final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
416             boolean isReadOnly) {
417         if ((leaf != null) && (toBuilder != null)) {
418             final String leafName = leaf.getQName().getLocalName();
419             String leafDesc = leaf.getDescription();
420             if (leafDesc == null) {
421                 leafDesc = "";
422             }
423
424             if (leafName != null) {
425                 final TypeDefinition<?> typeDef = leaf.getType();
426
427                 // TODO: properly resolve enum types
428                 final Type javaType = typeProvider
429                         .javaTypeForSchemaDefinitionType(typeDef);
430
431                 final GeneratedPropertyBuilder propBuilder = toBuilder
432                         .addProperty(BindingGeneratorUtil
433                                 .parseToClassName(leafName));
434
435                 propBuilder.setReadOnly(isReadOnly);
436                 propBuilder.addReturnType(javaType);
437                 propBuilder.addComment(leafDesc);
438
439                 toBuilder.addEqualsIdentity(propBuilder);
440                 toBuilder.addHashIdentity(propBuilder);
441                 toBuilder.addToStringProperty(propBuilder);
442
443                 return true;
444             }
445         }
446         return false;
447     }
448
449     private boolean resolveLeafListSchemaNode(
450             final GeneratedTypeBuilder typeBuilder,
451             final LeafListSchemaNode node) {
452         if ((node != null) && (typeBuilder != null)) {
453             final String nodeName = node.getQName().getLocalName();
454             String nodeDesc = node.getDescription();
455             if (nodeDesc == null) {
456                 nodeDesc = "";
457             }
458
459             if (nodeName != null) {
460                 final TypeDefinition<?> type = node.getType();
461                 final Type listType = Types.listTypeFor(typeProvider
462                         .javaTypeForSchemaDefinitionType(type));
463
464                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
465                 if (!node.isConfiguration()) {
466                     constructSetter(typeBuilder, nodeName, nodeDesc, listType);
467                 }
468                 return true;
469             }
470         }
471         return false;
472     }
473
474     private boolean resolveContainerSchemaNode(
475             final GeneratedTypeBuilder typeBuilder,
476             final ContainerSchemaNode node) {
477         if ((node != null) && (typeBuilder != null)) {
478             final String nodeName = node.getQName().getLocalName();
479
480             if (nodeName != null) {
481                 final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);
482                 constructGetter(typeBuilder, nodeName, "", rawGenType);
483
484                 return true;
485             }
486         }
487         return false;
488     }
489
490     private boolean resolveListSchemaNode(
491             final GeneratedTypeBuilder typeBuilder, final ListSchemaNode node) {
492         if ((node != null) && (typeBuilder != null)) {
493             final String nodeName = node.getQName().getLocalName();
494
495             if (nodeName != null) {
496                 final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);
497                 constructGetter(typeBuilder, nodeName, "",
498                         Types.listTypeFor(rawGenType));
499                 if (!node.isConfiguration()) {
500                     constructSetter(typeBuilder, nodeName, "",
501                             Types.listTypeFor(rawGenType));
502                 }
503                 return true;
504             }
505         }
506         return false;
507     }
508
509     private GeneratedTypeBuilder addRawInterfaceDefinition(
510             final DataSchemaNode schemaNode) {
511         if (schemaNode == null) {
512             return null;
513         }
514
515         final String packageName = BindingGeneratorUtil
516                 .packageNameForGeneratedType(basePackageName,
517                         schemaNode.getPath());
518         final String schemaNodeName = schemaNode.getQName().getLocalName();
519
520         if ((packageName != null) && (schemaNode != null)
521                 && (schemaNodeName != null)) {
522             final String genTypeName = BindingGeneratorUtil
523                     .parseToClassName(schemaNodeName);
524             final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(
525                     packageName, genTypeName);
526
527             if (!genTypeBuilders.containsKey(packageName)) {
528                 final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
529                 builders.put(genTypeName, newType);
530                 genTypeBuilders.put(packageName, builders);
531             } else {
532                 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
533                         .get(packageName);
534                 if (!builders.containsKey(genTypeName)) {
535                     builders.put(genTypeName, newType);
536                 }
537             }
538             return newType;
539         }
540         return null;
541     }
542
543     private String getterMethodName(final String methodName) {
544         final StringBuilder method = new StringBuilder();
545         method.append("get");
546         method.append(BindingGeneratorUtil.parseToClassName(methodName));
547         return method.toString();
548     }
549
550     private String setterMethodName(final String methodName) {
551         final StringBuilder method = new StringBuilder();
552         method.append("set");
553         method.append(BindingGeneratorUtil.parseToClassName(methodName));
554         return method.toString();
555     }
556
557     private MethodSignatureBuilder constructGetter(
558             final GeneratedTypeBuilder interfaceBuilder,
559             final String schemaNodeName, final String comment,
560             final Type returnType) {
561         final MethodSignatureBuilder getMethod = interfaceBuilder
562                 .addMethod(getterMethodName(schemaNodeName));
563
564         getMethod.addComment(comment);
565         getMethod.addReturnType(returnType);
566
567         return getMethod;
568     }
569
570     private MethodSignatureBuilder constructSetter(
571             final GeneratedTypeBuilder interfaceBuilder,
572             final String schemaNodeName, final String comment,
573             final Type parameterType) {
574         final MethodSignatureBuilder setMethod = interfaceBuilder
575                 .addMethod(setterMethodName(schemaNodeName));
576
577         setMethod.addComment(comment);
578         setMethod.addParameter(parameterType,
579                 BindingGeneratorUtil.parseToValidParamName(schemaNodeName));
580         setMethod.addReturnType(Types.voidType());
581
582         return setMethod;
583     }
584
585     private String resolveBasePackageName(final URI moduleNamespace,
586             final String yangVersion) {
587         final StringBuilder packageNameBuilder = new StringBuilder();
588
589         packageNameBuilder.append("org.opendaylight.yang.gen.v");
590         packageNameBuilder.append(yangVersion);
591         packageNameBuilder.append(".rev");
592         packageNameBuilder.append(calendar.get(Calendar.YEAR));
593         packageNameBuilder.append((calendar.get(Calendar.MONTH) + 1));
594         packageNameBuilder.append(calendar.get(Calendar.DAY_OF_MONTH));
595         packageNameBuilder.append(".");
596
597         String namespace = moduleNamespace.toString();
598         namespace = namespace.replace(":", ".");
599         namespace = namespace.replace("-", ".");
600
601         packageNameBuilder.append(namespace);
602
603         return packageNameBuilder.toString();
604     }
605
606     private List<Type> listToGenType(final ListSchemaNode list) {
607         if (list == null) {
608             return null;
609         }
610         final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(list);
611         final List<String> listKeys = listKeys(list);
612         GeneratedTOBuilder genTOBuilder = null;
613         if (listKeys.size() > 0) {
614             genTOBuilder = resolveListKey(list);
615         }
616
617         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
618         for (final DataSchemaNode node : schemaNodes) {
619
620             if (node instanceof LeafSchemaNode) {
621                 final LeafSchemaNode leaf = (LeafSchemaNode) node;
622                 if (!isPartOfListKey(leaf, listKeys)) {
623                     resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
624                 } else {
625                     resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
626                 }
627             } else if (node instanceof LeafListSchemaNode) {
628                 resolveLeafListSchemaNode(typeBuilder,
629                         (LeafListSchemaNode) node);
630             } else if (node instanceof ContainerSchemaNode) {
631                 resolveContainerSchemaNode(typeBuilder,
632                         (ContainerSchemaNode) node);
633             } else if (node instanceof ListSchemaNode) {
634                 resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);
635             }
636         }
637
638         final List<Type> genTypes = new ArrayList<Type>();
639         if (genTOBuilder != null) {
640             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
641             constructGetter(typeBuilder, genTO.getName(),
642                     "Returns Primary Key of Yang List Type", genTO);
643             genTypes.add(genTO);
644         }
645         genTypes.add(typeBuilder.toInstance());
646         return genTypes;
647     }
648
649     /**
650      * @param list
651      * @return
652      */
653     private GeneratedTOBuilder resolveListKey(final ListSchemaNode list) {
654         final String packageName = BindingGeneratorUtil
655                 .packageNameForGeneratedType(basePackageName, list.getPath());
656         final String listName = list.getQName().getLocalName() + "Key";
657
658         return BindingGeneratorUtil.schemaNodeToTransferObjectBuilder(
659                 packageName, list, listName);
660     }
661
662     private boolean isPartOfListKey(final LeafSchemaNode leaf,
663             final List<String> keys) {
664         if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
665             final String leafName = leaf.getQName().getLocalName();
666             if (keys.contains(leafName)) {
667                 return true;
668             }
669         }
670         return false;
671     }
672
673     private List<String> listKeys(final ListSchemaNode list) {
674         final List<String> listKeys = new ArrayList<String>();
675
676         if (list.getKeyDefinition() != null) {
677             final List<QName> keyDefinitions = list.getKeyDefinition();
678
679             for (final QName keyDefinition : keyDefinitions) {
680                 listKeys.add(keyDefinition.getLocalName());
681             }
682         }
683         return listKeys;
684     }
685
686     private GeneratedTypeBuilder resolveListTypeBuilder(
687             final ListSchemaNode list) {
688         final String packageName = BindingGeneratorUtil
689                 .packageNameForGeneratedType(basePackageName,
690                         list.getPath());
691         final String schemaNodeName = list.getQName().getLocalName();
692         final String genTypeName = BindingGeneratorUtil
693                 .parseToClassName(schemaNodeName);
694
695         GeneratedTypeBuilder typeBuilder = null;
696         if (genTypeBuilders.containsKey(packageName)) {
697             final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();
698             typeBuilder = builders.get(genTypeName);
699
700             if (null == typeBuilder) {
701                 typeBuilder = addRawInterfaceDefinition(list);
702             }
703         }
704         return typeBuilder;
705     }
706 }