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.yangtools.sal.binding.yang.types;
10 import static org.opendaylight.yangtools.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.yangtools.binding.generator.util.ReferencedTypeImpl;
22 import org.opendaylight.yangtools.binding.generator.util.TypeConstants;
23 import org.opendaylight.yangtools.binding.generator.util.Types;
24 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
25 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
26 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
27 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration;
28 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
29 import org.opendaylight.yangtools.sal.binding.model.api.Type;
30 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
31 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
32 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
33 import org.opendaylight.yangtools.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;
55 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
57 public final class TypeProviderImpl implements TypeProvider {
59 private final SchemaContext schemaContext;
60 private Map<String, Map<String, Type>> genTypeDefsContextMap;
61 private final Map<SchemaPath, Type> referencedTypes;
63 public TypeProviderImpl(final SchemaContext schemaContext) {
64 if (schemaContext == null) {
65 throw new IllegalArgumentException("Schema Context cannot be null!");
68 this.schemaContext = schemaContext;
69 this.genTypeDefsContextMap = new HashMap<>();
70 this.referencedTypes = new HashMap<>();
71 resolveTypeDefsFromContext();
74 public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
75 if (refTypePath == null) {
76 throw new IllegalArgumentException("Path reference of " + "Enumeration Type Definition cannot be NULL!");
79 if (refType == null) {
80 throw new IllegalArgumentException("Reference to Enumeration " + "Type cannot be NULL!");
82 referencedTypes.put(refTypePath, refType);
88 * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#
89 * javaTypeForYangType(java.lang.String)
92 public Type javaTypeForYangType(String type) {
93 Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type);
98 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition) {
99 Type returnType = null;
100 if (typeDefinition == null) {
101 throw new IllegalArgumentException("Type Definition cannot be NULL!");
103 if (typeDefinition.getQName() == null) {
104 throw new IllegalArgumentException(
105 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
107 if (typeDefinition.getQName().getLocalName() == null) {
108 throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!");
110 final String typedefName = typeDefinition.getQName().getLocalName();
111 if (typeDefinition instanceof ExtendedType) {
112 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
114 if (baseTypeDef instanceof LeafrefTypeDefinition) {
115 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) baseTypeDef;
116 returnType = provideTypeForLeafref(leafref);
117 } else if (baseTypeDef instanceof IdentityrefTypeDefinition) {
118 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) baseTypeDef;
119 returnType = returnTypeForIdentityref(idref);
120 } else if (baseTypeDef instanceof EnumTypeDefinition) {
121 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
122 returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
124 final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition);
125 if (module != null) {
126 final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
127 if (genTOs != null) {
128 returnType = genTOs.get(typedefName);
130 if (returnType == null) {
131 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
132 .javaTypeForSchemaDefinitionType(baseTypeDef);
137 if (typeDefinition instanceof LeafrefTypeDefinition) {
138 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
139 returnType = provideTypeForLeafref(leafref);
140 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
141 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
142 returnType = returnTypeForIdentityref(idref);
144 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition);
147 // TODO: add throw exception when we will be able to resolve ALL yang
149 // if (returnType == null) {
150 // throw new IllegalArgumentException("Type Provider can't resolve " +
151 // "type for specified Type Definition " + typedefName);
156 private Type returnTypeForIdentityref(IdentityrefTypeDefinition idref) {
157 QName baseIdQName = idref.getIdentity();
158 Module module = schemaContext.findModuleByNamespace(baseIdQName.getNamespace());
159 IdentitySchemaNode identity = null;
160 for (IdentitySchemaNode id : module.getIdentities()) {
161 if (id.getQName().equals(baseIdQName)) {
165 if (identity == null) {
166 throw new IllegalArgumentException("Target identity '" + baseIdQName + "' do not exists");
169 final String basePackageName = moduleNamespaceToPackageName(module);
170 final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
171 final String genTypeName = parseToClassName(identity.getQName().getLocalName());
173 Type baseType = Types.typeForClass(Class.class);
174 Type paramType = Types.wildcardTypeFor(packageName, genTypeName);
175 Type returnType = Types.parameterizedTypeFor(baseType, paramType);
179 public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition) {
180 Type returnType = null;
181 if (typeDefinition == null) {
182 throw new IllegalArgumentException("Type Definition cannot be NULL!");
184 if (typeDefinition.getQName() == null) {
185 throw new IllegalArgumentException(
186 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
188 if (typeDefinition.getQName() == null) {
189 throw new IllegalArgumentException("Type Definitions Local Name cannot be NULL!");
192 final String typedefName = typeDefinition.getQName().getLocalName();
193 if (typeDefinition instanceof ExtendedType) {
194 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
196 if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
197 final Module module = findParentModuleForTypeDefinition(schemaContext, typeDefinition);
199 if (module != null) {
200 final Map<String, Type> genTOs = genTypeDefsContextMap.get(module.getName());
201 if (genTOs != null) {
202 returnType = genTOs.get(typedefName);
210 private TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
211 if (extendTypeDef == null) {
212 throw new IllegalArgumentException("Type Definiition reference cannot be NULL!");
214 final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
215 if (baseTypeDef instanceof ExtendedType) {
216 return baseTypeDefForExtendedType(baseTypeDef);
223 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {
224 Type returnType = null;
225 if (leafrefType == null) {
226 throw new IllegalArgumentException("Leafref Type Definition reference cannot be NULL!");
229 if (leafrefType.getPathStatement() == null) {
230 throw new IllegalArgumentException("The Path Statement for Leafref Type Definition cannot be NULL!");
233 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
234 final String strXPath = xpath.toString();
236 if (strXPath != null) {
237 if (strXPath.contains("[")) {
238 returnType = Types.typeForClass(Object.class);
240 final Module module = findParentModuleForTypeDefinition(schemaContext, leafrefType);
241 if (module != null) {
242 final DataSchemaNode dataNode;
243 if (xpath.isAbsolute()) {
244 dataNode = findDataSchemaNode(schemaContext, module, xpath);
246 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, leafrefType, xpath);
249 if (leafContainsEnumDefinition(dataNode)) {
250 returnType = referencedTypes.get(dataNode.getPath());
251 } else if (leafListContainsEnumDefinition(dataNode)) {
252 returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath()));
254 returnType = resolveTypeFromDataSchemaNode(dataNode);
262 private boolean leafContainsEnumDefinition(final DataSchemaNode dataNode) {
263 if (dataNode instanceof LeafSchemaNode) {
264 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
265 if (leaf.getType() instanceof EnumTypeDefinition) {
272 private boolean leafListContainsEnumDefinition(final DataSchemaNode dataNode) {
273 if (dataNode instanceof LeafListSchemaNode) {
274 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
275 if (leafList.getType() instanceof EnumTypeDefinition) {
282 private Enumeration resolveEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName) {
283 if (enumTypeDef == null) {
284 throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!");
286 if (enumTypeDef.getValues() == null) {
287 throw new IllegalArgumentException("EnumTypeDefinition MUST contain at least ONE value definition!");
289 if (enumTypeDef.getQName() == null) {
290 throw new IllegalArgumentException("EnumTypeDefinition MUST contain NON-NULL QName!");
292 if (enumTypeDef.getQName().getLocalName() == null) {
293 throw new IllegalArgumentException("Local Name in EnumTypeDefinition QName cannot be NULL!");
296 final String enumerationName = parseToClassName(enumName);
298 Module module = findParentModuleForTypeDefinition(schemaContext, enumTypeDef);
299 final String basePackageName = moduleNamespaceToPackageName(module);
301 final EnumBuilder enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
302 updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
303 return enumBuilder.toInstance(null);
306 private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
307 final GeneratedTypeBuilder typeBuilder) {
308 if (enumTypeDef == null) {
309 throw new IllegalArgumentException("EnumTypeDefinition reference cannot be NULL!");
311 if (enumTypeDef.getValues() == null) {
312 throw new IllegalArgumentException("EnumTypeDefinition MUST contain at least ONE value definition!");
314 if (enumTypeDef.getQName() == null) {
315 throw new IllegalArgumentException("EnumTypeDefinition MUST contain NON-NULL QName!");
317 if (enumTypeDef.getQName().getLocalName() == null) {
318 throw new IllegalArgumentException("Local Name in EnumTypeDefinition QName cannot be NULL!");
320 if (typeBuilder == null) {
321 throw new IllegalArgumentException("Generated Type Builder reference cannot be NULL!");
324 final String enumerationName = parseToClassName(enumName);
325 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
327 updateEnumPairsFromEnumTypeDef(enumTypeDef, enumBuilder);
332 private void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef, final EnumBuilder enumBuilder) {
333 if (enumBuilder != null) {
334 final List<EnumPair> enums = enumTypeDef.getValues();
337 for (final EnumPair enumPair : enums) {
338 if (enumPair != null) {
339 final String enumPairName = parseToClassName(enumPair.getName());
340 Integer enumPairValue = enumPair.getValue();
342 if (enumPairValue == null) {
343 enumPairValue = listIndex;
345 enumBuilder.addValue(enumPairName, enumPairValue);
353 private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {
354 Type returnType = null;
355 if (dataNode != null) {
356 if (dataNode instanceof LeafSchemaNode) {
357 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
358 returnType = javaTypeForSchemaDefinitionType(leaf.getType());
359 } else if (dataNode instanceof LeafListSchemaNode) {
360 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
361 returnType = javaTypeForSchemaDefinitionType(leafList.getType());
367 private void resolveTypeDefsFromContext() {
368 final Set<Module> modules = schemaContext.getModules();
369 if (modules == null) {
370 throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
372 final Module[] modulesArray = new Module[modules.size()];
374 for (Module modul : modules) {
375 modulesArray[i++] = modul;
377 final List<Module> modulesSortedByDependency = ModuleDependencySort.sort(modulesArray);
379 for (final Module module : modulesSortedByDependency) {
380 if (module == null) {
383 final String moduleName = module.getName();
384 final String basePackageName = moduleNamespaceToPackageName(module);
386 final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
387 final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
389 final Map<String, Type> typeMap = new HashMap<>();
390 genTypeDefsContextMap.put(moduleName, typeMap);
392 if ((listTypeDefinitions != null) && (basePackageName != null)) {
393 for (final TypeDefinition<?> typedef : listTypeDefinitions) {
394 typedefToGeneratedType(basePackageName, moduleName, typedef);
400 private Type typedefToGeneratedType(final String basePackageName, final String moduleName,
401 final TypeDefinition<?> typedef) {
402 if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
404 final String typedefName = typedef.getQName().getLocalName();
405 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
406 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
407 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
408 Type returnType = null;
409 if (innerTypeDefinition instanceof ExtendedType) {
410 ExtendedType extendedTypeDef = (ExtendedType) innerTypeDefinition;
411 returnType = resolveExtendedTypeFromTypeDef(extendedTypeDef, basePackageName, typedefName,
413 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
414 final GeneratedTOBuilder genTOBuilder = addUnionGeneratedTypeDefinition(basePackageName, typedef,
416 returnType = genTOBuilder.toInstance();
417 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
418 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
419 returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
421 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
422 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
423 final GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName,
424 bitsTypeDefinition, typedefName);
425 returnType = genTOBuilder.toInstance();
428 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
429 .javaTypeForSchemaDefinitionType(innerTypeDefinition);
431 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
433 if (returnType != null) {
434 final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
435 if (typeMap != null) {
436 typeMap.put(typedefName, returnType);
445 private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
446 final Type javaType) {
447 if (javaType != null) {
448 final String typedefName = typedef.getQName().getLocalName();
449 final String propertyName = parseToValidParamName(typedefName);
451 final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
453 final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
455 genPropBuilder.setReturnType(javaType);
456 genTOBuilder.addEqualsIdentity(genPropBuilder);
457 genTOBuilder.addHashIdentity(genPropBuilder);
458 genTOBuilder.addToStringProperty(genPropBuilder);
459 if (javaType == BaseYangTypes.STRING_TYPE) {
460 if (typedef instanceof ExtendedType) {
461 final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
462 addStringRegExAsConstant(genTOBuilder, regExps);
465 return genTOBuilder.toInstance();
470 public GeneratedTOBuilder addUnionGeneratedTypeDefinition(final String basePackageName,
471 final TypeDefinition<?> typedef, String typeDefName) {
472 if (basePackageName == null) {
473 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
475 if (typedef == null) {
476 throw new IllegalArgumentException("Type Definition cannot be NULL!");
478 if (typedef.getQName() == null) {
479 throw new IllegalArgumentException(
480 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
483 final TypeDefinition<?> baseTypeDefinition = typedef.getBaseType();
484 if ((baseTypeDefinition != null) && (baseTypeDefinition instanceof UnionTypeDefinition)) {
485 final Module parentModule = findParentModuleForTypeDefinition(schemaContext, typedef);
486 final UnionTypeDefinition unionTypeDef = (UnionTypeDefinition) baseTypeDefinition;
487 final List<TypeDefinition<?>> unionTypes = unionTypeDef.getTypes();
489 Map<String, Type> genTOsMap = null;
490 if (parentModule != null && parentModule.getName() != null) {
491 genTOsMap = genTypeDefsContextMap.get(parentModule.getName());
494 final GeneratedTOBuilder unionGenTransObject;
495 if (typeDefName != null && !typeDefName.isEmpty()) {
496 final String typeName = parseToClassName(typeDefName);
497 unionGenTransObject = new GeneratedTOBuilderImpl(basePackageName, typeName);
499 unionGenTransObject = typedefToTransferObject(basePackageName, typedef);
501 unionGenTransObject.setIsUnion(true);
503 final List<String> regularExpressions = new ArrayList<String>();
504 for (final TypeDefinition<?> unionType : unionTypes) {
505 final String typeName = unionType.getQName().getLocalName();
506 if (unionType instanceof ExtendedType) {
507 final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType);
508 if (unionTypeModule != null && unionTypeModule.getName() != null) {
509 final Map<String, Type> innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName());
510 Type genTransferObject = null;
511 if (innerGenTOs != null) {
512 genTransferObject = innerGenTOs.get(typeName);
514 if (genTransferObject != null) {
515 updateUnionTypeAsProperty(unionGenTransObject, genTransferObject,
516 genTransferObject.getName());
518 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionType);
519 if (typeName.equals(baseType.getQName().getLocalName())) {
520 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
521 .javaTypeForSchemaDefinitionType(baseType);
522 if (javaType != null) {
523 updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName);
526 if (baseType instanceof StringType) {
527 regularExpressions.addAll(resolveRegExpressionsFromTypedef((ExtendedType) unionType));
531 } else if (unionType instanceof EnumTypeDefinition) {
532 final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition((EnumTypeDefinition) unionType,
533 typeName, unionGenTransObject);
534 final Type enumRefType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
535 updateUnionTypeAsProperty(unionGenTransObject, enumRefType, typeName);
537 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
538 .javaTypeForSchemaDefinitionType(unionType);
539 if (javaType != null) {
540 updateUnionTypeAsProperty(unionGenTransObject, javaType, typeName);
544 if (!regularExpressions.isEmpty()) {
545 addStringRegExAsConstant(unionGenTransObject, regularExpressions);
548 genTOsMap.put(typedef.getQName().getLocalName(), unionGenTransObject.toInstance());
549 return unionGenTransObject;
554 private void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type,
555 final String propertyName) {
556 if (unionGenTransObject != null && type != null) {
557 if (!unionGenTransObject.containsProperty(propertyName)) {
558 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
559 .addProperty(parseToValidParamName(propertyName));
560 propBuilder.setReturnType(type);
562 if (!(type instanceof Enumeration)) {
563 unionGenTransObject.addEqualsIdentity(propBuilder);
564 unionGenTransObject.addHashIdentity(propBuilder);
565 unionGenTransObject.addToStringProperty(propBuilder);
571 private GeneratedTOBuilder typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef) {
573 final String packageName = packageNameForGeneratedType(basePackageName, typedef.getPath());
574 final String typeDefTOName = typedef.getQName().getLocalName();
576 if ((packageName != null) && (typedef != null) && (typeDefTOName != null)) {
577 final String genTOName = parseToClassName(typeDefTOName);
578 final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName);
585 public GeneratedTOBuilder bitsTypedefToTransferObject(final String basePackageName,
586 final TypeDefinition<?> typeDef, String typeDefName) {
588 if (typeDef == null) {
589 throw new IllegalArgumentException("typeDef cannot be NULL!");
591 if (basePackageName == null) {
592 throw new IllegalArgumentException("Base Package Name cannot be NULL!");
595 if (typeDef instanceof BitsTypeDefinition) {
596 BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
598 final String typeName = parseToClassName(typeDefName);
599 final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
601 final List<Bit> bitList = bitsTypeDefinition.getBits();
602 GeneratedPropertyBuilder genPropertyBuilder;
603 for (final Bit bit : bitList) {
604 String name = bit.getName();
605 genPropertyBuilder = genTOBuilder.addProperty(parseToValidParamName(name));
606 genPropertyBuilder.setReadOnly(false);
607 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
609 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
610 genTOBuilder.addHashIdentity(genPropertyBuilder);
611 genTOBuilder.addToStringProperty(genPropertyBuilder);
619 private List<String> resolveRegExpressionsFromTypedef(ExtendedType typedef) {
620 final List<String> regExps = new ArrayList<String>();
621 if (typedef == null) {
622 throw new IllegalArgumentException("typedef can't be null");
624 final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
625 if (strTypeDef instanceof StringType) {
626 final List<PatternConstraint> patternConstraints = typedef.getPatterns();
627 if (!patternConstraints.isEmpty()) {
629 String modifiedRegEx;
630 for (PatternConstraint patternConstraint : patternConstraints) {
631 regEx = patternConstraint.getRegularExpression();
632 modifiedRegEx = StringEscapeUtils.escapeJava(regEx);
633 regExps.add(modifiedRegEx);
640 private void addStringRegExAsConstant(GeneratedTOBuilder genTOBuilder, List<String> regularExpressions) {
641 if (genTOBuilder == null)
642 throw new IllegalArgumentException("genTOBuilder can't be null");
643 if (regularExpressions == null)
644 throw new IllegalArgumentException("regularExpressions can't be null");
646 if (!regularExpressions.isEmpty()) {
647 genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), TypeConstants.PATTERN_CONSTANT_NAME,
652 private GeneratedTransferObject resolveExtendedTypeFromTypeDef(final ExtendedType extendedType,
653 final String basePackageName, final String typedefName, final String moduleName) {
655 if (extendedType == null) {
656 throw new IllegalArgumentException("Extended type cannot be NULL!");
658 if (basePackageName == null) {
659 throw new IllegalArgumentException("String with base package name cannot be NULL!");
661 if (typedefName == null) {
662 throw new IllegalArgumentException("String with type definition name cannot be NULL!");
665 final String typeDefName = parseToClassName(typedefName);
666 final String lowTypeDef = extendedType.getQName().getLocalName();
667 final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName);
669 final Module parentModule = findParentModuleForTypeDefinition(schemaContext, extendedType);
671 Map<String, Type> typeMap = null;
672 if (parentModule != null) {
673 typeMap = genTypeDefsContextMap.get(parentModule.getName());
676 if (typeMap != null) {
677 Type type = typeMap.get(lowTypeDef);
678 if (type instanceof GeneratedTransferObject) {
679 genTOBuilder.setExtendsType((GeneratedTransferObject) type);
683 return genTOBuilder.toInstance();
687 * The method find out for each type definition how many immersion (depth)
688 * is necessary to get to the base type. Every type definition is inserted
689 * to the map which key is depth and value is list of type definitions with
690 * equal depth. In next step are lists from this map concatenated to one
691 * list in ascending order according to their depth. All type definitions
692 * are in the list behind all type definitions on which depends.
694 * @param unsortedTypeDefinitions
695 * represents list of type definitions
696 * @return list of type definitions sorted according their each other
697 * dependencies (type definitions which are depend on other type
698 * definitions are in list behind them).
700 private List<TypeDefinition<?>> sortTypeDefinitionAccordingDepth(
701 final Set<TypeDefinition<?>> unsortedTypeDefinitions) {
702 List<TypeDefinition<?>> sortedTypeDefinition = new ArrayList<>();
704 Map<Integer, List<TypeDefinition<?>>> typeDefinitionsDepths = new TreeMap<>();
705 for (TypeDefinition<?> unsortedTypeDefinition : unsortedTypeDefinitions) {
706 final int depth = getTypeDefinitionDepth(unsortedTypeDefinition);
707 List<TypeDefinition<?>> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth);
708 if (typeDefinitionsConcreteDepth == null) {
709 typeDefinitionsConcreteDepth = new ArrayList<TypeDefinition<?>>();
710 typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth);
712 typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
715 Set<Integer> depths = typeDefinitionsDepths.keySet(); // keys are in
717 for (Integer depth : depths) {
718 sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth));
721 return sortedTypeDefinition;
725 * The method return how many immersion is necessary to get from type
726 * definition to base type.
728 * @param typeDefinition
729 * is type definition for which is depth looked for.
730 * @return how many immersion is necessary to get from type definition to
733 private int getTypeDefinitionDepth(final TypeDefinition<?> typeDefinition) {
734 if (typeDefinition == null) {
735 throw new IllegalArgumentException("Type definition can't be null");
738 TypeDefinition<?> baseType = typeDefinition.getBaseType();
740 if (baseType instanceof ExtendedType) {
741 depth = depth + getTypeDefinitionDepth(typeDefinition.getBaseType());
742 } else if (baseType instanceof UnionType) {
743 List<TypeDefinition<?>> childTypeDefinitions = ((UnionType) baseType).getTypes();
744 int maxChildDepth = 0;
746 for (TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
747 childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition.getBaseType());
748 if (childDepth > maxChildDepth) {
749 maxChildDepth = childDepth;
752 return maxChildDepth;