Maping of union leaf a bits leaf YANG type to JAVA inner classes.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / yang / types / TypeProviderImpl.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.yang.types;
9
10 import org.apache.commons.lang.StringEscapeUtils;
11 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
12 import org.opendaylight.controller.binding.generator.util.TypeConstants;
13 import org.opendaylight.controller.binding.generator.util.Types;
14 import org.opendaylight.controller.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
15 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
16 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
17 import org.opendaylight.controller.sal.binding.model.api.Enumeration;
18 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
19 import org.opendaylight.controller.sal.binding.model.api.Type;
20 import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
21 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
22 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
23 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
24 import org.opendaylight.controller.yang.common.QName;
25 import org.opendaylight.controller.yang.model.api.*;
26 import org.opendaylight.controller.yang.model.api.type.*;
27 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
28 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
29 import org.opendaylight.controller.yang.model.util.ExtendedType;
30 import org.opendaylight.controller.yang.model.util.StringType;
31
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37
38 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
39 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.*;
40
41 public final class TypeProviderImpl implements TypeProvider {
42
43     private final SchemaContext schemaContext;
44     private Map<String, Map<String, Type>> genTypeDefsContextMap;
45     private final Map<SchemaPath, Type> referencedTypes;
46
47     public TypeProviderImpl(final SchemaContext schemaContext) {
48         if (schemaContext == null) {
49             throw new IllegalArgumentException("Schema Context cannot be null!");
50         }
51
52         this.schemaContext = schemaContext;
53         this.genTypeDefsContextMap = new HashMap<>();
54         this.referencedTypes = new HashMap<>();
55         resolveTypeDefsFromContext();
56     }
57
58     public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
59         if (refTypePath == null) {
60             throw new IllegalArgumentException("Path reference of " + "Enumeration Type Definition cannot be NULL!");
61         }
62
63         if (refType == null) {
64             throw new IllegalArgumentException("Reference to Enumeration " + "Type cannot be NULL!");
65         }
66         referencedTypes.put(refTypePath, refType);
67     }
68
69     /*
70      * (non-Javadoc)
71      * 
72      * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#
73      * javaTypeForYangType(java.lang.String)
74      */
75     @Override
76     public Type javaTypeForYangType(String type) {
77         Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type);
78         return t;
79     }
80
81     @Override
82     public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition) {
83         Type returnType = null;
84         if (typeDefinition == null) {
85             throw new IllegalArgumentException("Type Definition cannot be NULL!");
86         }
87         if (typeDefinition.getQName() == null) {
88             throw new IllegalArgumentException(
89                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
90         }
91         if (typeDefinition.getQName().getLocalName() == null) {
92             throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!");
93         }
94         final String typedefName = typeDefinition.getQName().getLocalName();
95         if (typeDefinition instanceof ExtendedType) {
96             final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
97
98             if (baseTypeDef instanceof LeafrefTypeDefinition) {
99                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef;
100                 returnType = provideTypeForLeafref(leafref);
101             } else if (baseTypeDef instanceof IdentityrefTypeDefinition) {
102                 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) baseTypeDef;
103                 returnType = returnTypeForIdentityref(idref);
104             } else if (baseTypeDef instanceof EnumTypeDefinition) {
105                 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
106                 returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
107             } else {
108                 final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition);
109                 if (module != null) {
110                     final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
111                     if (genTOs != null) {
112                         returnType = genTOs.get(typedefName);
113                     }
114                     if (returnType == null) {
115                         returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
116                                 .javaTypeForSchemaDefinitionType(baseTypeDef);
117                     }
118                 }
119             }
120         } else {
121             if (typeDefinition instanceof LeafrefTypeDefinition) {
122                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
123                 returnType = provideTypeForLeafref(leafref);
124             } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
125                 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
126                 returnType = returnTypeForIdentityref(idref);
127             } else {
128                 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition);
129             }
130         }
131         // TODO: add throw exception when we will be able to resolve ALL yang
132         // types!
133         // if (returnType == null) {
134         // throw new IllegalArgumentException("Type Provider can't resolve " +
135         // "type for specified Type Definition " + typedefName);
136         // }
137         return returnType;
138     }
139
140     private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) {
141         QName baseIdQName = idref.getIdentity();
142         Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace());
143         IdentitySchemaNode identity = null;
144         for (IdentitySchemaNode id : module.getIdentities()) {
145             if (id.getQName().equals(baseIdQName)) {
146                 identity = id;
147             }
148         }
149         if (identity == null) {
150             throw new IllegalArgumentException("Target identity '" + baseIdQName + "' do not exists");
151         }
152
153         final String basePackageName = moduleNamespaceToPackageName(module);
154         final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
155         final String genTypeName = parseToClassName(identity.getQName().getLocalName());
156
157         Type baseType = Types.typeForClass(Class.class);
158         Type paramType = Types.wildcardTypeFor(packageName, genTypeName);
159         Type returnType = Types.parameterizedTypeFor(baseType, paramType);
160         return returnType;
161     }
162
163     public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition) {
164         Type returnType = null;
165         if (typeDefinition == null) {
166             throw new IllegalArgumentException("Type Definition cannot be NULL!");
167         }
168         if (typeDefinition.getQName() == null) {
169             throw new IllegalArgumentException(
170                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
171         }
172         if (typeDefinition.getQName() == null) {
173             throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!");
174         }
175
176         final String typedefName = typeDefinition.getQName().getLocalName();
177         if (typeDefinition instanceof ExtendedType) {
178             final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
179
180             if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
181                 final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition);
182
183                 if (module != null) {
184                     final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
185                     if (genTOs != null) {
186                         returnType = genTOs.get(typedefName);
187                     }
188                 }
189             }
190         }
191         return returnType;
192     }
193
194     private TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
195         if (extendTypeDef == null) {
196             throw new IllegalArgumentException("Type Definiition reference cannot be NULL!");
197         }
198         final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
199         if (baseTypeDef instanceof ExtendedType) {
200             return baseTypeDefForExtendedType(baseTypeDef);
201         } else {
202             return baseTypeDef;
203         }
204
205     }
206
207     public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {
208         Type returnType = null;
209         if (leafrefType == null) {
210             throw new IllegalArgumentException("Leafref Type Definition reference cannot be NULL!");
211         }
212
213         if (leafrefType.getPathStatement() == null) {
214             throw new IllegalArgumentException("The Path Statement for Leafref Type Definition cannot be NULL!");
215         }
216
217         final RevisionAwareXPath xpath = leafrefType.getPathStatement();
218         final String strXPath = xpath.toString();
219
220         if (strXPath != null) {
221             if (strXPath.matches(".*//[.* | .*//].*")) {
222                 returnType = Types.typeForClass(Object.class);
223             } else {
224                 final Module module = findParentModuleForTypeDefinition(schemaContext, leafrefType);
225                 if (module != null) {
226                     final DataSchemaNode dataNode;
227                     if (xpath.isAbsolute()) {
228                         dataNode = findDataSchemaNode(schemaContext, module, xpath);
229                     } else {
230                         dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, leafrefType, xpath);
231                     }
232
233                     if (leafContainsEnumDefinition(dataNode)) {
234                         returnType = referencedTypes.get(dataNode.getPath());
235                     } else if (leafListContainsEnumDefinition(dataNode)) {
236                         returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath()));
237                     } else {
238                         returnType = resolveTypeFromDataSchemaNode(dataNode);
239                     }
240                 }
241             }
242         }
243         return returnType;
244     }
245
246     private boolean leafContainsEnumDefinition(final DataSchemaNode dataNode) {
247         if (dataNode instanceof LeafSchemaNode) {
248             final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
249             if (leaf.getType() instanceof EnumTypeDefinition) {
250                 return true;
251             }
252         }
253         return false;
254     }
255
256     private boolean leafListContainsEnumDefinition(final DataSchemaNode dataNode) {
257         if (dataNode instanceof LeafListSchemaNode) {
258             final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
259             if (leafList.getType() instanceof EnumTypeDefinition) {
260                 return true;
261             }
262         }
263         return false;
264     }
265
266     private Enumeration resolveEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName) {
267         if (enumTypeDef == null) {
268             throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!");
269         }
270         if (enumTypeDef.getValues() == null) {
271             throw new IllegalArgumentException("EnumTypeDefinition MUST contain at least ONE value definition!");
272         }
273         if (enumTypeDef.getQName() == null) {
274             throw new IllegalArgumentException("EnumTypeDefinition MUST contain NON-NULL QName!");
275         }
276         if (enumTypeDef.getQName().getLocalName() == null) {
277             throw new IllegalArgumentException("Local Name in EnumTypeDefinition QName cannot be NULL!");
278         }
279
280         final String enumerationName = parseToClassName(enumName);
281
282         Module module = findParentModuleForTypeDefinition(schemaContext, enumTypeDef);
283         final String basePackageName = moduleNamespaceToPackageName(module);
284
285         final EnumBuilder enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
286         updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
287         return enumBuilder.toInstance(null);
288     }
289
290     private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
291             final GeneratedTypeBuilder typeBuilder) {
292         if (enumTypeDef == null) {
293             throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!");
294         }
295         if (enumTypeDef.getValues() == null) {
296             throw new IllegalArgumentException("EnumTypeDefinition MUST contain at least ONE value definition!");
297         }
298         if (enumTypeDef.getQName() == null) {
299             throw new IllegalArgumentException("EnumTypeDefinition MUST contain NON-NULL QName!");
300         }
301         if (enumTypeDef.getQName().getLocalName() == null) {
302             throw new IllegalArgumentException("Local Name in EnumTypeDefinition QName cannot be NULL!");
303         }
304         if (typeBuilder == null) {
305             throw new IllegalArgumentException("Generated Type Builder reference cannot be NULL!");
306         }
307
308         final String enumerationName = parseToClassName(enumName);
309         final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
310
311         updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
312
313         return enumBuilder;
314     }
315
316     private void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef, final EnumBuilder enumBuilder) {
317         if (enumBuilder != null) {
318             final List<EnumPair> enums = enumTypeDef.getValues();
319             if (enums != null) {
320                 int listIndex = 0;
321                 for (final EnumPair enumPair : enums) {
322                     if (enumPair != null) {
323                         final String enumPairName = parseToClassName(enumPair.getName());
324                         Integer enumPairValue = enumPair.getValue();
325
326                         if (enumPairValue == null) {
327                             enumPairValue = listIndex;
328                         }
329                         enumBuilder.addValue(enumPairName, enumPairValue);
330                         listIndex++;
331                     }
332                 }
333             }
334         }
335     }
336
337     private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {
338         Type returnType = null;
339         if (dataNode != null) {
340             if (dataNode instanceof LeafSchemaNode) {
341                 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
342                 returnType = javaTypeForSchemaDefinitionType(leaf.getType());
343             } else if (dataNode instanceof LeafListSchemaNode) {
344                 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
345                 returnType = javaTypeForSchemaDefinitionType(leafList.getType());
346             }
347         }
348         return returnType;
349     }
350
351     private void resolveTypeDefsFromContext() {
352         final Set<Module> modules = schemaContext.getModules();
353         if (modules == null) {
354             throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
355         }
356         for (final Module module : modules) {
357             if (module == null) {
358                 continue;
359             }
360             final String moduleName = module.getName();
361             final String basePackageName = moduleNamespaceToPackageName(module);
362
363             final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
364
365             final Map<String, Type> typeMap = new HashMap<>();
366             genTypeDefsContextMap.put(moduleName, typeMap);
367
368             if ((typeDefinitions != null) && (basePackageName != null)) {
369                 for (final TypeDefinition<?> typedef : typeDefinitions) {
370                     typedefToGeneratedType(basePackageName, moduleName, typedef);
371                 }
372                 final List<ExtendedType> extUnions = UnionDependencySort.sort(typeDefinitions);
373                 for (final ExtendedType extUnionType : extUnions) {
374                     addUnionGeneratedTypeDefinition(basePackageName, extUnionType, null);
375                 }
376             }
377         }
378     }
379
380     private Type typedefToGeneratedType(final String basePackageName, final String moduleName,
381             final TypeDefinition<?> typedef) {
382         if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
383
384             final String typedefName = typedef.getQName().getLocalName();
385             final TypeDefinition<?> baseTypeDefinition = baseTypeDefForExtendedType(typedef);
386             if (!(baseTypeDefinition instanceof LeafrefTypeDefinition)
387                     && !(baseTypeDefinition instanceof IdentityrefTypeDefinition)) {
388                 Type returnType;
389                 if (baseTypeDefinition instanceof EnumTypeDefinition) {
390                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDefinition;
391                     returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
392
393                 } else if (baseTypeDefinition instanceof BitsTypeDefinition) {
394                     final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) baseTypeDefinition;
395                     GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName, bitsTypeDefinition,
396                             typedefName);
397                     returnType = genTOBuilder.toInstance();
398
399                 } else {
400                     final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
401                             .javaTypeForSchemaDefinitionType(baseTypeDefinition);
402
403                     returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
404                 }
405                 if (returnType != null) {
406                     final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
407                     if (typeMap != null) {
408                         typeMap.put(typedefName, returnType);
409                     }
410                     return returnType;
411                 }
412             }
413         }
414         return null;
415     }
416
417     private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
418             final Type javaType) {
419         if (javaType != null) {
420             final String typedefName = typedef.getQName().getLocalName();
421             final String propertyName = parseToValidParamName(typedefName);
422
423             final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
424
425             final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
426
427             genPropBuilder.setReturnType(javaType);
428             genTOBuilder.addEqualsIdentity(genPropBuilder);
429             genTOBuilder.addHashIdentity(genPropBuilder);
430             genTOBuilder.addToStringProperty(genPropBuilder);
431
432             if (typedef instanceof ExtendedType) {
433                 final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
434                 addStringRegExAsConstant(genTOBuilder, regExps);
435             }
436
437             return genTOBuilder.toInstance();
438         }
439         return null;
440     }
441
442     public GeneratedTOBuilder addUnionGeneratedTypeDefinition(final String basePackageName,
443             final TypeDefinition<?> typedef, String typeDefName) {
444         if (basePackageName == null) {
445             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
446         }
447         if (typedef == null) {
448             throw new IllegalArgumentException("Type Definition cannot be NULL!");
449         }
450         if (typedef.getQName() == null) {
451             throw new IllegalArgumentException(
452                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
453         }
454
455         final TypeDefinition<?> baseTypeDefinition = typedef.getBaseType();
456         if ((baseTypeDefinition != null) && (baseTypeDefinition instanceof UnionTypeDefinition)) {
457             final Module parentModule = findParentModuleForTypeDefinition(schemaContext, typedef);
458             final UnionTypeDefinition unionTypeDef = (UnionTypeDefinition) baseTypeDefinition;
459             final List<TypeDefinition<?>> unionTypes = unionTypeDef.getTypes();
460
461             Map<String, Type> genTOsMap = null;
462             if (parentModule != null && parentModule.getName() != null) {
463                 genTOsMap = genTypeDefsContextMap.get(parentModule.getName());
464             }
465
466             final GeneratedTOBuilder unionGenTransObject;
467             if (typeDefName != null && !typeDefName.isEmpty()) {
468                 final String typeName = parseToClassName(typeDefName);
469                 unionGenTransObject = new GeneratedTOBuilderImpl(basePackageName, typeName);
470             } else {
471                 unionGenTransObject = typedefToTransferObject(basePackageName, typedef);
472             }
473             unionGenTransObject.setIsUnion(true);
474
475             final List<String> regularExpressions = new ArrayList<String>();
476             for (final TypeDefinition<?> unionType : unionTypes) {
477                 final String typeName = unionType.getQName().getLocalName();
478                 if (unionType instanceof ExtendedType) {
479                     final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType);
480                     if (unionTypeModule != null && unionTypeModule.getName() != null) {
481                         final Map<String, Type> innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName());
482
483                         final GeneratedTransferObject genTransferObject = (GeneratedTransferObject) innerGenTOs
484                                 .get(typeName);
485                         if (genTransferObject != null) {
486                             updateUnionTypeAsProperty(unionGenTransObject, genTransferObject,
487                                     genTransferObject.getName());
488                         } else {
489                             final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionType);
490                             if (typeName.equals(baseType.getQName().getLocalName())) {
491                                 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
492                                         .javaTypeForSchemaDefinitionType(baseType);
493                                 if (javaType != null) {
494                                     updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName);
495                                 }
496                             }
497                             if (baseType instanceof StringType) {
498                                 regularExpressions.addAll(resolveRegExpressionsFromTypedef((ExtendedType) unionType));
499                             }
500                         }
501                     }
502                 } else if (unionType instanceof EnumTypeDefinition) {
503                     final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition((EnumTypeDefinition) unionType,
504                             typeName, unionGenTransObject);
505                     final Type enumRefType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
506                     updateUnionTypeAsProperty(unionGenTransObject, enumRefType, typeName);
507                 } else {
508                     final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
509                             .javaTypeForSchemaDefinitionType(unionType);
510                     if (javaType != null) {
511                         updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName);
512                     }
513                 }
514             }
515             if (!regularExpressions.isEmpty()) {
516                 addStringRegExAsConstant(unionGenTransObject, regularExpressions);
517             }
518
519             genTOsMap.put(typedef.getQName().getLocalName(), unionGenTransObject.toInstance());
520             return unionGenTransObject;
521         }
522         return null;
523     }
524
525     private void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type,
526             final String propertyName) {
527         if (unionGenTransObject != null && type != null) {
528             if (!unionGenTransObject.containsProperty(propertyName)) {
529                 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
530                         .addProperty(parseToValidParamName(propertyName));
531                 propBuilder.setReturnType(type);
532
533                 if (!(type instanceof Enumeration)) {
534                     unionGenTransObject.addEqualsIdentity(propBuilder);
535                     unionGenTransObject.addHashIdentity(propBuilder);
536                     unionGenTransObject.addToStringProperty(propBuilder);
537                 }
538             }
539         }
540     }
541
542     private GeneratedTOBuilder typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef) {
543
544         final String packageName = packageNameForGeneratedType(basePackageName, typedef.getPath());
545         final String typeDefTOName = typedef.getQName().getLocalName();
546
547         if ((packageName != null) && (typedef != null) && (typeDefTOName != null)) {
548             final String genTOName = parseToClassName(typeDefTOName);
549             final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName);
550
551             return newType;
552         }
553         return null;
554     }
555
556     public GeneratedTOBuilder bitsTypedefToTransferObject(final String basePackageName,
557             final TypeDefinition<?> typeDef, String typeDefName) {
558
559         if (typeDef == null) {
560             throw new IllegalArgumentException("typeDef cannot be NULL!");
561         }
562         if (basePackageName == null) {
563             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
564         }
565
566         if (typeDef instanceof BitsTypeDefinition) {
567             BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
568
569             final String typeName = parseToClassName(typeDefName);
570             final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
571
572             final List<Bit> bitList = bitsTypeDefinition.getBits();
573             GeneratedPropertyBuilder genPropertyBuilder;
574             for (final Bit bit : bitList) {
575                 String name = bit.getName();
576                 genPropertyBuilder = genTOBuilder.addProperty(parseToValidParamName(name));
577                 genPropertyBuilder.setReadOnly(false);
578                 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
579
580                 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
581                 genTOBuilder.addHashIdentity(genPropertyBuilder);
582                 genTOBuilder.addToStringProperty(genPropertyBuilder);
583             }
584
585             return genTOBuilder;
586         }
587         return null;
588     }
589
590     private List<String> resolveRegExpressionsFromTypedef(ExtendedType typedef) {
591         final List<String> regExps = new ArrayList<String>();
592         if (typedef == null) {
593             throw new IllegalArgumentException("typedef can't be null");
594         }
595         final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
596         if (strTypeDef instanceof StringType) {
597             final List<PatternConstraint> patternConstraints = typedef.getPatterns();
598             if (!patternConstraints.isEmpty()) {
599                 String regEx;
600                 String modifiedRegEx;
601                 for (PatternConstraint patternConstraint : patternConstraints) {
602                     regEx = patternConstraint.getRegularExpression();
603                     modifiedRegEx = StringEscapeUtils.escapeJava(regEx);
604                     regExps.add(modifiedRegEx);
605                 }
606             }
607         }
608         return regExps;
609     }
610
611     private void addStringRegExAsConstant(GeneratedTOBuilder genTOBuilder, List<String> regularExpressions) {
612         if (genTOBuilder == null)
613             throw new IllegalArgumentException("genTOBuilder can't be null");
614         if (regularExpressions == null)
615             throw new IllegalArgumentException("regularExpressions can't be null");
616
617         if (!regularExpressions.isEmpty()) {
618             genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), TypeConstants.PATTERN_CONSTANT_NAME,
619                     regularExpressions);
620         }
621     }
622
623 }