2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.sal.binding.yang.types;
10 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
11 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
18 import java.util.TreeMap;
20 import org.apache.commons.lang.StringEscapeUtils;
21 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
22 import org.opendaylight.controller.binding.generator.util.TypeConstants;
23 import org.opendaylight.controller.binding.generator.util.Types;
24 import org.opendaylight.controller.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
25 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
26 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
27 import org.opendaylight.controller.sal.binding.model.api.Enumeration;
28 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
29 import org.opendaylight.controller.sal.binding.model.api.Type;
30 import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
31 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
32 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
33 import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
34 import org.opendaylight.yangtools.yang.common.QName;
35 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.Module;
40 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
41 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
42 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
43 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
44 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
45 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
46 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
47 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
48 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
49 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
50 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
51 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
52 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
53 import org.opendaylight.yangtools.yang.model.util.StringType;
54 import org.opendaylight.yangtools.yang.model.util.UnionType;
56 public final class TypeProviderImpl implements TypeProvider {
58 private final SchemaContext schemaContext;
59 private Map<String, Map<String, Type>> genTypeDefsContextMap;
60 private final Map<SchemaPath, Type> referencedTypes;
62 public TypeProviderImpl(final SchemaContext schemaContext) {
63 if (schemaContext == null) {
64 throw new IllegalArgumentException("Schema Context cannot be null!");
67 this.schemaContext = schemaContext;
68 this.genTypeDefsContextMap = new HashMap<>();
69 this.referencedTypes = new HashMap<>();
70 resolveTypeDefsFromContext();
73 public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
74 if (refTypePath == null) {
75 throw new IllegalArgumentException("Path reference of " + "Enumeration Type Definition cannot be NULL!");
78 if (refType == null) {
79 throw new IllegalArgumentException("Reference to Enumeration " + "Type cannot be NULL!");
81 referencedTypes.put(refTypePath, refType);
87 * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#
88 * javaTypeForYangType(java.lang.String)
91 public Type javaTypeForYangType(String type) {
92 Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type);
97 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition) {
98 Type returnType = null;
99 if (typeDefinition == null) {
100 throw new IllegalArgumentException("Type Definition cannot be NULL!");
102 if (typeDefinition.getQName() == null) {
103 throw new IllegalArgumentException(
104 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
106 if (typeDefinition.getQName().getLocalName() == null) {
107 throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!");
109 final String typedefName = typeDefinition.getQName().getLocalName();
110 if (typeDefinition instanceof ExtendedType) {
111 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
113 if (baseTypeDef instanceof LeafrefTypeDefinition) {
114 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef;
115 returnType = provideTypeForLeafref(leafref);
116 } else if (baseTypeDef instanceof IdentityrefTypeDefinition) {
117 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) baseTypeDef;
118 returnType = returnTypeForIdentityref(idref);
119 } else if (baseTypeDef instanceof EnumTypeDefinition) {
120 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
121 returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
123 final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition);
124 if (module != null) {
125 final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
126 if (genTOs != null) {
127 returnType = genTOs.get(typedefName);
129 if (returnType == null) {
130 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
131 .javaTypeForSchemaDefinitionType(baseTypeDef);
136 if (typeDefinition instanceof LeafrefTypeDefinition) {
137 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
138 returnType = provideTypeForLeafref(leafref);
139 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
140 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
141 returnType = returnTypeForIdentityref(idref);
143 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition);
146 // TODO: add throw exception when we will be able to resolve ALL yang
148 // if (returnType == null) {
149 // throw new IllegalArgumentException("Type Provider can't resolve " +
150 // "type for specified Type Definition " + typedefName);
155 private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) {
156 QName baseIdQName = idref.getIdentity();
157 Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace());
158 IdentitySchemaNode identity = null;
159 for (IdentitySchemaNode id : module.getIdentities()) {
160 if (id.getQName().equals(baseIdQName)) {
164 if (identity == null) {
165 throw new IllegalArgumentException("Target identity '" + baseIdQName + "' do not exists");
168 final String basePackageName = moduleNamespaceToPackageName(module);
169 final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
170 final String genTypeName = parseToClassName(identity.getQName().getLocalName());
172 Type baseType = Types.typeForClass(Class.class);
173 Type paramType = Types.wildcardTypeFor(packageName, genTypeName);
174 Type returnType = Types.parameterizedTypeFor(baseType, paramType);
178 public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition) {
179 Type returnType = null;
180 if (typeDefinition == null) {
181 throw new IllegalArgumentException("Type Definition cannot be NULL!");
183 if (typeDefinition.getQName() == null) {
184 throw new IllegalArgumentException(
185 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
187 if (typeDefinition.getQName() == null) {
188 throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!");
191 final String typedefName = typeDefinition.getQName().getLocalName();
192 if (typeDefinition instanceof ExtendedType) {
193 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
195 if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
196 final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition);
198 if (module != null) {
199 final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
200 if (genTOs != null) {
201 returnType = genTOs.get(typedefName);
209 private TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
210 if (extendTypeDef == null) {
211 throw new IllegalArgumentException("Type Definiition reference cannot be NULL!");
213 final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
214 if (baseTypeDef instanceof ExtendedType) {
215 return baseTypeDefForExtendedType(baseTypeDef);
222 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {
223 Type returnType = null;
224 if (leafrefType == null) {
225 throw new IllegalArgumentException("Leafref Type Definition reference cannot be NULL!");
228 if (leafrefType.getPathStatement() == null) {
229 throw new IllegalArgumentException("The Path Statement for Leafref Type Definition cannot be NULL!");
232 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
233 final String strXPath = xpath.toString();
235 if (strXPath != null) {
236 if (strXPath.contains("[")) {
237 returnType = Types.typeForClass(Object.class);
239 final Module module = findParentModuleForTypeDefinition(schemaContext, leafrefType);
240 if (module != null) {
241 final DataSchemaNode dataNode;
242 if (xpath.isAbsolute()) {
243 dataNode = findDataSchemaNode(schemaContext, module, xpath);
245 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, leafrefType, xpath);
248 if (leafContainsEnumDefinition(dataNode)) {
249 returnType = referencedTypes.get(dataNode.getPath());
250 } else if (leafListContainsEnumDefinition(dataNode)) {
251 returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath()));
253 returnType = resolveTypeFromDataSchemaNode(dataNode);
261 private boolean leafContainsEnumDefinition(final DataSchemaNode dataNode) {
262 if (dataNode instanceof LeafSchemaNode) {
263 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
264 if (leaf.getType() instanceof EnumTypeDefinition) {
271 private boolean leafListContainsEnumDefinition(final DataSchemaNode dataNode) {
272 if (dataNode instanceof LeafListSchemaNode) {
273 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
274 if (leafList.getType() instanceof EnumTypeDefinition) {
281 private Enumeration resolveEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName) {
282 if (enumTypeDef == null) {
283 throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!");
285 if (enumTypeDef.getValues() == null) {
286 throw new IllegalArgumentException("EnumTypeDefinition MUST contain at least ONE value definition!");
288 if (enumTypeDef.getQName() == null) {
289 throw new IllegalArgumentException("EnumTypeDefinition MUST contain NON-NULL QName!");
291 if (enumTypeDef.getQName().getLocalName() == null) {
292 throw new IllegalArgumentException("Local Name in EnumTypeDefinition QName cannot be NULL!");
295 final String enumerationName = parseToClassName(enumName);
297 Module module = findParentModuleForTypeDefinition(schemaContext, enumTypeDef);
298 final String basePackageName = moduleNamespaceToPackageName(module);
300 final EnumBuilder enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
301 updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
302 return enumBuilder.toInstance(null);
305 private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
306 final GeneratedTypeBuilder typeBuilder) {
307 if (enumTypeDef == null) {
308 throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!");
310 if (enumTypeDef.getValues() == null) {
311 throw new IllegalArgumentException("EnumTypeDefinition MUST contain at least ONE value definition!");
313 if (enumTypeDef.getQName() == null) {
314 throw new IllegalArgumentException("EnumTypeDefinition MUST contain NON-NULL QName!");
316 if (enumTypeDef.getQName().getLocalName() == null) {
317 throw new IllegalArgumentException("Local Name in EnumTypeDefinition QName cannot be NULL!");
319 if (typeBuilder == null) {
320 throw new IllegalArgumentException("Generated Type Builder reference cannot be NULL!");
323 final String enumerationName = parseToClassName(enumName);
324 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
326 updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
331 private void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef, final EnumBuilder enumBuilder) {
332 if (enumBuilder != null) {
333 final List<EnumPair> enums = enumTypeDef.getValues();
336 for (final EnumPair enumPair : enums) {
337 if (enumPair != null) {
338 final String enumPairName = parseToClassName(enumPair.getName());
339 Integer enumPairValue = enumPair.getValue();
341 if (enumPairValue == null) {
342 enumPairValue = listIndex;
344 enumBuilder.addValue(enumPairName, enumPairValue);
352 private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {
353 Type returnType = null;
354 if (dataNode != null) {
355 if (dataNode instanceof LeafSchemaNode) {
356 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
357 returnType = javaTypeForSchemaDefinitionType(leaf.getType());
358 } else if (dataNode instanceof LeafListSchemaNode) {
359 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
360 returnType = javaTypeForSchemaDefinitionType(leafList.getType());
366 private void resolveTypeDefsFromContext() {
367 final Set<Module> modules = schemaContext.getModules();
368 if (modules == null) {
369 throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
371 for (final Module module : modules) {
372 if (module == null) {
375 final String moduleName = module.getName();
376 final String basePackageName = moduleNamespaceToPackageName(module);
378 final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
379 final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
381 final Map<String, Type> typeMap = new HashMap<>();
382 genTypeDefsContextMap.put(moduleName, typeMap);
384 if ((listTypeDefinitions != null) && (basePackageName != null)) {
385 for (final TypeDefinition<?> typedef : listTypeDefinitions) {
386 typedefToGeneratedType(basePackageName, moduleName, typedef);
392 private Type typedefToGeneratedType(final String basePackageName, final String moduleName,
393 final TypeDefinition<?> typedef) {
394 if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
396 final String typedefName = typedef.getQName().getLocalName();
397 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
398 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
399 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
400 Type returnType = null;
401 if (innerTypeDefinition instanceof ExtendedType) {
402 ExtendedType extendedTypeDef = (ExtendedType) innerTypeDefinition;
403 returnType = resolveExtendedTypeFromTypeDef(extendedTypeDef, basePackageName, typedefName,
405 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
406 final GeneratedTOBuilder genTOBuilder = addUnionGeneratedTypeDefinition(basePackageName, typedef,
408 returnType = genTOBuilder.toInstance();
409 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
410 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
411 returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
413 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
414 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
415 final GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName,
416 bitsTypeDefinition, typedefName);
417 returnType = genTOBuilder.toInstance();
420 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
421 .javaTypeForSchemaDefinitionType(innerTypeDefinition);
423 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
425 if (returnType != null) {
426 final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
427 if (typeMap != null) {
428 typeMap.put(typedefName, returnType);
437 private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
438 final Type javaType) {
439 if (javaType != null) {
440 final String typedefName = typedef.getQName().getLocalName();
441 final String propertyName = parseToValidParamName(typedefName);
443 final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
445 final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
447 genPropBuilder.setReturnType(javaType);
448 genTOBuilder.addEqualsIdentity(genPropBuilder);
449 genTOBuilder.addHashIdentity(genPropBuilder);
450 genTOBuilder.addToStringProperty(genPropBuilder);
451 if (javaType == BaseYangTypes.STRING_TYPE) {
452 if (typedef instanceof ExtendedType) {
453 final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
454 addStringRegExAsConstant(genTOBuilder, regExps);
457 return genTOBuilder.toInstance();
462 public GeneratedTOBuilder addUnionGeneratedTypeDefinition(final String basePackageName,
463 final TypeDefinition<?> typedef, String typeDefName) {
464 if (basePackageName == null) {
465 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
467 if (typedef == null) {
468 throw new IllegalArgumentException("Type Definition cannot be NULL!");
470 if (typedef.getQName() == null) {
471 throw new IllegalArgumentException(
472 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
475 final TypeDefinition<?> baseTypeDefinition = typedef.getBaseType();
476 if ((baseTypeDefinition != null) && (baseTypeDefinition instanceof UnionTypeDefinition)) {
477 final Module parentModule = findParentModuleForTypeDefinition(schemaContext, typedef);
478 final UnionTypeDefinition unionTypeDef = (UnionTypeDefinition) baseTypeDefinition;
479 final List<TypeDefinition<?>> unionTypes = unionTypeDef.getTypes();
481 Map<String, Type> genTOsMap = null;
482 if (parentModule != null && parentModule.getName() != null) {
483 genTOsMap = genTypeDefsContextMap.get(parentModule.getName());
486 final GeneratedTOBuilder unionGenTransObject;
487 if (typeDefName != null && !typeDefName.isEmpty()) {
488 final String typeName = parseToClassName(typeDefName);
489 unionGenTransObject = new GeneratedTOBuilderImpl(basePackageName, typeName);
491 unionGenTransObject = typedefToTransferObject(basePackageName, typedef);
493 unionGenTransObject.setIsUnion(true);
495 final List<String> regularExpressions = new ArrayList<String>();
496 for (final TypeDefinition<?> unionType : unionTypes) {
497 final String typeName = unionType.getQName().getLocalName();
498 if (unionType instanceof ExtendedType) {
499 final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType);
500 if (unionTypeModule != null && unionTypeModule.getName() != null) {
501 final Map<String, Type> innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName());
502 Type genTransferObject = null;
503 if (innerGenTOs != null) {
504 genTransferObject = innerGenTOs.get(typeName);
506 if (genTransferObject != null) {
507 updateUnionTypeAsProperty(unionGenTransObject, genTransferObject,
508 genTransferObject.getName());
510 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionType);
511 if (typeName.equals(baseType.getQName().getLocalName())) {
512 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
513 .javaTypeForSchemaDefinitionType(baseType);
514 if (javaType != null) {
515 updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName);
518 if (baseType instanceof StringType) {
519 regularExpressions.addAll(resolveRegExpressionsFromTypedef((ExtendedType) unionType));
523 } else if (unionType instanceof EnumTypeDefinition) {
524 final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition((EnumTypeDefinition) unionType,
525 typeName, unionGenTransObject);
526 final Type enumRefType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
527 updateUnionTypeAsProperty(unionGenTransObject, enumRefType, typeName);
529 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
530 .javaTypeForSchemaDefinitionType(unionType);
531 if (javaType != null) {
532 updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName);
536 if (!regularExpressions.isEmpty()) {
537 addStringRegExAsConstant(unionGenTransObject, regularExpressions);
540 genTOsMap.put(typedef.getQName().getLocalName(), unionGenTransObject.toInstance());
541 return unionGenTransObject;
546 private void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type,
547 final String propertyName) {
548 if (unionGenTransObject != null && type != null) {
549 if (!unionGenTransObject.containsProperty(propertyName)) {
550 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
551 .addProperty(parseToValidParamName(propertyName));
552 propBuilder.setReturnType(type);
554 if (!(type instanceof Enumeration)) {
555 unionGenTransObject.addEqualsIdentity(propBuilder);
556 unionGenTransObject.addHashIdentity(propBuilder);
557 unionGenTransObject.addToStringProperty(propBuilder);
563 private GeneratedTOBuilder typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef) {
565 final String packageName = packageNameForGeneratedType(basePackageName, typedef.getPath());
566 final String typeDefTOName = typedef.getQName().getLocalName();
568 if ((packageName != null) && (typedef != null) && (typeDefTOName != null)) {
569 final String genTOName = parseToClassName(typeDefTOName);
570 final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName);
577 public GeneratedTOBuilder bitsTypedefToTransferObject(final String basePackageName,
578 final TypeDefinition<?> typeDef, String typeDefName) {
580 if (typeDef == null) {
581 throw new IllegalArgumentException("typeDef cannot be NULL!");
583 if (basePackageName == null) {
584 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
587 if (typeDef instanceof BitsTypeDefinition) {
588 BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
590 final String typeName = parseToClassName(typeDefName);
591 final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
593 final List<Bit> bitList = bitsTypeDefinition.getBits();
594 GeneratedPropertyBuilder genPropertyBuilder;
595 for (final Bit bit : bitList) {
596 String name = bit.getName();
597 genPropertyBuilder = genTOBuilder.addProperty(parseToValidParamName(name));
598 genPropertyBuilder.setReadOnly(false);
599 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
601 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
602 genTOBuilder.addHashIdentity(genPropertyBuilder);
603 genTOBuilder.addToStringProperty(genPropertyBuilder);
611 private List<String> resolveRegExpressionsFromTypedef(ExtendedType typedef) {
612 final List<String> regExps = new ArrayList<String>();
613 if (typedef == null) {
614 throw new IllegalArgumentException("typedef can't be null");
616 final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
617 if (strTypeDef instanceof StringType) {
618 final List<PatternConstraint> patternConstraints = typedef.getPatterns();
619 if (!patternConstraints.isEmpty()) {
621 String modifiedRegEx;
622 for (PatternConstraint patternConstraint : patternConstraints) {
623 regEx = patternConstraint.getRegularExpression();
624 modifiedRegEx = StringEscapeUtils.escapeJava(regEx);
625 regExps.add(modifiedRegEx);
632 private void addStringRegExAsConstant(GeneratedTOBuilder genTOBuilder, List<String> regularExpressions) {
633 if (genTOBuilder == null)
634 throw new IllegalArgumentException("genTOBuilder can't be null");
635 if (regularExpressions == null)
636 throw new IllegalArgumentException("regularExpressions can't be null");
638 if (!regularExpressions.isEmpty()) {
639 genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), TypeConstants.PATTERN_CONSTANT_NAME,
644 private GeneratedTransferObject resolveExtendedTypeFromTypeDef(final ExtendedType extendedType,
645 final String basePackageName, final String typedefName, final String moduleName) {
647 if (extendedType == null) {
648 throw new IllegalArgumentException("Extended type cannot be NULL!");
650 if (basePackageName == null) {
651 throw new IllegalArgumentException("String with base package name cannot be NULL!");
653 if (typedefName == null) {
654 throw new IllegalArgumentException("String with type definition name cannot be NULL!");
657 final String typeDefName = parseToClassName(typedefName);
658 final String lowTypeDef = extendedType.getQName().getLocalName();
659 final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName);
661 final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
662 if (typeMap != null) {
663 Type type = typeMap.get(lowTypeDef);
664 if (type instanceof GeneratedTransferObject) {
665 genTOBuilder.setExtendsType((GeneratedTransferObject) type);
669 return genTOBuilder.toInstance();
673 * The method find out for each type definition how many immersion (depth)
674 * is necessary to get to the base type. Every type definition is inserted
675 * to the map which key is depth and value is list of type definitions with
676 * equal depth. In next step are lists from this map concatenated to one
677 * list in ascending order according to their depth. All type definitions
678 * are in the list behind all type definitions on which depends.
680 * @param unsortedTypeDefinitions
681 * represents list of type definitions
682 * @return list of type definitions sorted according their each other
683 * dependencies (type definitions which are depend on other type
684 * definitions are in list behind them).
686 private List<TypeDefinition<?>> sortTypeDefinitionAccordingDepth(
687 final Set<TypeDefinition<?>> unsortedTypeDefinitions) {
688 List<TypeDefinition<?>> sortedTypeDefinition = new ArrayList<>();
690 Map<Integer, List<TypeDefinition<?>>> typeDefinitionsDepths = new TreeMap<>();
691 for (TypeDefinition<?> unsortedTypeDefinition : unsortedTypeDefinitions) {
692 final int depth = getTypeDefinitionDepth(unsortedTypeDefinition);
693 List<TypeDefinition<?>> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth);
694 if (typeDefinitionsConcreteDepth == null) {
695 typeDefinitionsConcreteDepth = new ArrayList<TypeDefinition<?>>();
696 typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth);
698 typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
701 Set<Integer> depths = typeDefinitionsDepths.keySet(); // keys are in
703 for (Integer depth : depths) {
704 sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth));
707 return sortedTypeDefinition;
711 * The method return how many immersion is necessary to get from type
712 * definition to base type.
714 * @param typeDefinition
715 * is type definition for which is depth looked for.
716 * @return how many immersion is necessary to get from type definition to
719 private int getTypeDefinitionDepth(final TypeDefinition<?> typeDefinition) {
720 if (typeDefinition == null) {
721 throw new IllegalArgumentException("Type definition can't be null");
724 TypeDefinition<?> baseType = typeDefinition.getBaseType();
726 if (baseType instanceof ExtendedType) {
727 depth = depth + getTypeDefinitionDepth(typeDefinition.getBaseType());
728 } else if (baseType instanceof UnionType) {
729 List<TypeDefinition<?>> childTypeDefinitions = ((UnionType) baseType).getTypes();
730 int maxChildDepth = 0;
732 for (TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
733 childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition.getBaseType());
734 if (childDepth > maxChildDepth) {
735 maxChildDepth = childDepth;
738 return maxChildDepth;