2 * Copyright (c) 2017 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
9 package org.opendaylight.mdsal.binding.javav2.generator.yang.types;
11 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
12 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameWithNamespacePrefix;
13 import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.getOuterClassPackageName;
14 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.addStringRegExAsConstant;
15 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.baseTypeDefForExtendedType;
16 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.getAllTypedefs;
17 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.getParentModule;
18 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.makeSerializable;
19 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.provideGeneratedTOFromExtendedType;
20 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.provideTypeForEnum;
21 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.resolveRegExpressionsFromTypedef;
22 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.sortTypeDefinitionAccordingDepth;
23 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.wrapJavaTypeIntoTO;
24 import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.getRootPackageName;
25 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
26 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
27 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
29 import com.google.common.annotations.Beta;
30 import com.google.common.base.Preconditions;
31 import com.google.common.base.Strings;
32 import com.google.common.collect.Sets;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.Date;
36 import java.util.HashMap;
37 import java.util.Iterator;
38 import java.util.List;
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
44 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
45 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
46 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
47 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
48 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
49 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
50 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
51 import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
52 import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
53 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty;
54 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
55 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
56 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
57 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
58 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
59 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
60 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilderBase;
61 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
62 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
63 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
64 import org.opendaylight.yangtools.yang.common.QName;
65 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
66 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
67 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
68 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
69 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
70 import org.opendaylight.yangtools.yang.model.api.Module;
71 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
72 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
73 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
74 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
75 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
76 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
77 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
78 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
79 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
80 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
81 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
82 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
83 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
84 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
85 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
86 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
87 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
88 import org.slf4j.Logger;
89 import org.slf4j.LoggerFactory;
92 public final class TypeProviderImpl implements TypeProvider {
94 private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
95 private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
98 * Contains the schema data red from YANG files.
100 private final SchemaContext schemaContext;
103 * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
105 private final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
108 * Map which maps schema paths to JAVA <code>Type</code>.
110 private final Map<SchemaPath, Type> referencedTypes;
113 * Map for additional types e.g unions
115 private final Map<Module, Set<Type>> additionalTypes;
118 * Creates new instance of class <code>TypeProviderImpl</code>.
120 * @param schemaContext
121 * contains the schema data red from YANG files
122 * @throws IllegalArgumentException
123 * if <code>schemaContext</code> equal null.
125 public TypeProviderImpl(final SchemaContext schemaContext) {
126 this.schemaContext = schemaContext;
127 this.genTypeDefsContextMap = new HashMap<>();
128 this.referencedTypes = new HashMap<>();
129 this.additionalTypes = new HashMap<>();
130 resolveTypeDefsFromContext(schemaContext, this.genTypeDefsContextMap, this.additionalTypes);
134 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode,
135 ModuleContext context) {
136 return javaTypeForSchemaDefinitionType(type, parentNode, null, context);
140 * Converts schema definition type <code>typeDefinition</code> to JAVA
144 * type definition which is converted to JAVA type
145 * @throws IllegalArgumentException
147 * <li>if <code>typeDefinition</code> equal null</li>
148 * <li>if QName of <code>typeDefinition</code> equal null</li>
149 * <li>if name of <code>typeDefinition</code> equal null</li>
153 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode, final
154 Restrictions restrictions, ModuleContext context) {
155 return javaTypeForSchemaDefType(type, parentNode, restrictions, this.schemaContext, this
156 .genTypeDefsContextMap, context);
160 public String getTypeDefaultConstruction(final LeafSchemaNode node) {
165 public String getConstructorPropertyName(final SchemaNode node) {
170 public String getParamNameFromType(final TypeDefinition<?> type) {
174 public Map<String, Map<Date, Map<String, Type>>> getGenTypeDefsContextMap() {
175 return this.genTypeDefsContextMap;
179 * Passes through all modules and through all its type definitions and
180 * convert it to generated types.
182 * The modules are firstly sorted by mutual dependencies. The modules are
183 * sequentially passed. All type definitions of a module are at the
184 * beginning sorted so that type definition with less amount of references
185 * to other type definition are processed first.<br />
186 * For each module is created mapping record in the map
187 * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap}
188 * which map current module name to the map which maps type names to
189 * returned types (generated types).
192 private void resolveTypeDefsFromContext(final SchemaContext schemaContext, final Map<String, Map<Date, Map<String,
193 Type>>> genTypeDefsContextMap, final Map<Module, Set<Type>> additionalTypes) {
195 final Set<Module> modules = schemaContext.getModules();
196 Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
197 final List<Module> modulesSortedByDependency = ModuleDependencySort.sort(modules);
199 for (final Module module : modulesSortedByDependency) {
200 Map<Date, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
201 if (dateTypeMap == null) {
202 dateTypeMap = new HashMap<>();
204 dateTypeMap.put(module.getRevision(), Collections.emptyMap());
205 genTypeDefsContextMap.put(module.getName(), dateTypeMap);
208 modulesSortedByDependency.stream().filter(module -> module != null).forEach(module -> {
209 ModuleContext context = new ModuleContext();
210 final String basePackageName = packageNameWithNamespacePrefix(getRootPackageName(module),
211 BindingNamespaceType.Typedef);
212 final List<TypeDefinition<?>> typeDefinitions = getAllTypedefs(module);
213 final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
214 if (listTypeDefinitions != null) {
215 for (final TypeDefinition<?> typedef : listTypeDefinitions) {
216 typedefToGeneratedType(basePackageName, module, typedef, genTypeDefsContextMap,
217 additionalTypes, schemaContext, context);
224 * Converts <code>typeDefinition</code> to concrete JAVA <code>Type</code>.
226 * @param typeDefinition
227 * type definition which should be converted to JAVA
229 * @return JAVA <code>Type</code> which represents
230 * <code>typeDefinition</code>
231 * @throws IllegalArgumentException
233 * <li>if <code>typeDefinition</code> equal null</li>
234 * <li>if Q name of <code>typeDefinition</code></li>
235 * <li>if name of <code>typeDefinition</code></li>
238 public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
239 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
240 Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
241 "Type Definitions Local Name cannot be NULL!");
243 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
244 if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
245 final Module module = findParentModule(this.schemaContext, parentNode);
247 if (module != null) {
248 final Map<Date, Map<String, Type>> modulesByDate = this.genTypeDefsContextMap.get(module.getName());
249 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
250 if (genTOs != null) {
251 return genTOs.get(typeDefinition.getQName().getLocalName());
259 * Puts <code>refType</code> to map with key <code>refTypePath</code>
262 * schema path used as the map key
264 * type which represents the map value
265 * @throws IllegalArgumentException
267 * <li>if <code>refTypePath</code> equal null</li>
268 * <li>if <code>refType</code> equal null</li>
272 public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
273 Preconditions.checkArgument(refTypePath != null,
274 "Path reference of Enumeration Type Definition cannot be NULL!");
275 Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!");
276 this.referencedTypes.put(refTypePath, refType);
280 * Converts <code>typeDef</code> which should be of the type
281 * <code>BitsTypeDefinition</code> to <code>GeneratedTOBuilder</code>.
283 * All the bits of the typeDef are added to returning generated TO as
286 * @param basePackageName
287 * string with name of package to which the module belongs
289 * type definition from which is the generated TO builder created
291 * string with the name for generated TO builder
292 * @return generated TO builder which represents <code>typeDef</code>
293 * @throws IllegalArgumentException
295 * <li>if <code>typeDef</code> equals null</li>
296 * <li>if <code>basePackageName</code> equals null</li>
299 @SuppressWarnings({ "rawtypes", "unchecked" })
300 public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
301 final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName, ModuleContext context) {
303 Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
304 Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
306 if (typeDef instanceof BitsTypeDefinition) {
307 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
309 final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName,
310 true, false, context);
311 final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
313 genTOBuilder.setDescription(typedefDescription);
314 genTOBuilder.setReference(typeDef.getReference());
315 genTOBuilder.setSchemaPath((List) typeDef.getPath().getPathFromRoot());
316 genTOBuilder.setModuleName(moduleName);
317 genTOBuilder.setBaseType(typeDef);
319 final List<Bit> bitList = bitsTypeDefinition.getBits();
320 GeneratedPropertyBuilder genPropertyBuilder;
321 for (final Bit bit : bitList) {
322 final String name = bit.getName();
324 genTOBuilder.addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
325 genPropertyBuilder.setReadOnly(true);
326 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
328 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
329 genTOBuilder.addHashIdentity(genPropertyBuilder);
330 genTOBuilder.addToStringProperty(genPropertyBuilder);
339 * Converts <code>typedef</code> to generated TO with
340 * <code>typeDefName</code>. Every union type from <code>typedef</code> is
341 * added to generated TO builder as property.
343 * @param basePackageName
344 * string with name of package to which the module belongs
346 * type definition which should be of type
347 * <code>UnionTypeDefinition</code>
349 * string with name for generated TO
350 * @return generated TO builder which represents <code>typedef</code>
351 * @throws NullPointerException
353 * <li>if <code>basePackageName</code> is null</li>
354 * <li>if <code>typedef</code> is null</li>
355 * <li>if QName of <code>typedef</code> is null</li>
358 @SuppressWarnings({ "rawtypes", "unchecked" })
359 public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
360 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
361 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
362 Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
363 Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
364 Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
366 final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
367 final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
368 final Module module = findParentModule(schemaContext, parentNode);
370 final GeneratedTOBuilderImpl unionGenTOBuilder;
371 unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName, true, false,
373 final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
374 unionGenTOBuilder.setDescription(typedefDescription);
375 unionGenTOBuilder.setReference(typedef.getReference());
376 unionGenTOBuilder.setSchemaPath((List) typedef.getPath().getPathFromRoot());
377 unionGenTOBuilder.setModuleName(module.getName());
379 generatedTOBuilders.add(unionGenTOBuilder);
380 unionGenTOBuilder.setIsUnion(true);
381 final List<String> regularExpressions = new ArrayList<>();
382 for (final TypeDefinition<?> unionType : unionTypes) {
383 final String unionTypeName = unionType.getQName().getLocalName();
384 if (unionType.getBaseType() != null) {
385 resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, regularExpressions,
386 parentNode, schemaContext, genTypeDefsContextMap);
387 } else if (unionType instanceof UnionTypeDefinition) {
388 generatedTOBuilders.add(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
389 unionGenTOBuilder.getFullyQualifiedName(), parentNode, schemaContext, genTypeDefsContextMap,
391 } else if (unionType instanceof EnumTypeDefinition) {
392 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
393 unionTypeName, unionGenTOBuilder, context);
394 updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
396 final Type javaType = javaTypeForSchemaDefType(unionType, parentNode, null, schemaContext,
397 genTypeDefsContextMap, context);
398 updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
401 if (!regularExpressions.isEmpty()) {
402 addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
405 //storeGenTO(typedef, unionGenTOBuilder, parentNode);
407 return generatedTOBuilders;
410 public Map<Module, Set<Type>> getAdditionalTypes() {
411 return this.additionalTypes;
414 public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) {
415 if (!Strings.isNullOrEmpty(units)) {
416 to.addConstant(Types.STRING, "Units", "\"" + units + "\"");
417 final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
418 prop.setReturnType(Types.STRING);
419 to.addToStringProperty(prop);
423 private Type javaTypeForSchemaDefType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
424 final Restrictions r, final SchemaContext schemaContext,
425 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
426 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
427 final String typedefName = typeDefinition.getQName().getLocalName();
428 Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
430 // Deal with base types
431 if (typeDefinition.getBaseType() == null) {
432 // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type
433 // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates
434 // a base type which holds these constraints.
435 if (typeDefinition instanceof DecimalTypeDefinition) {
436 final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType
437 (typeDefinition, parentNode, r, null);
443 // Deal with leafrefs/identityrefs
444 Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode, schemaContext,
445 genTypeDefsContextMap, context);
450 ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode,
453 LOG.debug("Failed to resolve Java type for {}", typeDefinition);
459 Type returnType = javaTypeForExtendedType(typeDefinition, schemaContext, genTypeDefsContextMap, context);
460 if (r != null && !r.isEmpty() && returnType instanceof GeneratedTransferObject) {
461 final GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
462 final Module module = findParentModule(schemaContext, parentNode);
463 final Module module1 = findParentModule(schemaContext, typeDefinition);
464 final String basePackageName = BindingMapping.getRootPackageName(module);
465 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typeDefinition
466 .getPath(), BindingNamespaceType.Typedef);
467 final String genTOName =
468 JavaIdentifierNormalizer.normalizeSpecificIdentifier(typedefName, JavaIdentifier.CLASS);
469 final String name = packageName + "." + genTOName;
470 if (module.equals(module1) && !(returnType.getFullyQualifiedName().equals(name))) {
471 returnType = shadedTOWithRestrictions(gto, r, context);
479 * @param basePackageName
480 * string with name of package to which the module belongs
482 * string with the name of the module for to which the
483 * <code>typedef</code> belongs
485 * type definition of the node for which should be creted JAVA
486 * <code>Type</code> (usually generated TO)
487 * @return JAVA <code>Type</code> representation of <code>typedef</code> or
488 * <code>null</code> value if <code>basePackageName</code> or
489 * <code>modulName</code> or <code>typedef</code> or Q name of
490 * <code>typedef</code> equals <code>null</code>
492 private Type typedefToGeneratedType(final String basePackageName, final Module module,
493 final TypeDefinition<?> typedef, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
494 final Map<Module, Set<Type>> additionalTypes, final SchemaContext schemaContext, ModuleContext context) {
495 final String moduleName = module.getName();
496 final Date moduleRevision = module.getRevision();
497 if ((basePackageName != null) && (moduleName != null) && (typedef != null)) {
498 final String typedefName = typedef.getQName().getLocalName();
499 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
500 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
501 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
503 if (innerTypeDefinition.getBaseType() != null) {
504 returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName,
505 module.getName(), schemaContext, genTypeDefsContextMap, context);
506 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
507 final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
508 (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef, schemaContext,
509 genTypeDefsContextMap, context);
510 genTOBuilder.setTypedef(true);
511 genTOBuilder.setIsUnion(true);
512 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
513 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
514 returnType = genTOBuilder.toInstance();
515 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
516 // enums are automatically Serializable
517 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
518 // TODO units for typedef enum
519 returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef, schemaContext, context);
520 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
521 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
522 final GeneratedTOBuilder genTOBuilder =
523 provideGeneratedTOBuilderForBitsTypeDefinition(
524 basePackageName, bitsTypeDefinition, typedefName, module.getName(), context);
525 genTOBuilder.setTypedef(true);
526 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
527 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
528 returnType = genTOBuilder.toInstance();
530 final Type javaType = javaTypeForSchemaDefType(innerTypeDefinition, typedef, null,
531 schemaContext, genTypeDefsContextMap, context);
532 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName(), context);
534 if (returnType != null) {
535 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
536 Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
537 if (typeMap != null) {
538 if (typeMap.isEmpty()) {
539 typeMap = new HashMap<>(4);
540 modulesByDate.put(moduleRevision, typeMap);
542 typeMap.put(typedefName, returnType);
552 * Returns JAVA <code>Type</code> for instances of the type
553 * <code>ExtendedType</code>.
555 * @param typeDefinition
556 * type definition which is converted to JAVA <code>Type</code>
557 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
559 private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition, final SchemaContext schemaContext,
560 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
562 final String typedefName = typeDefinition.getQName().getLocalName();
563 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
564 Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition, schemaContext,
565 genTypeDefsContextMap, context);
566 if (returnType == null) {
567 final Module module = findParentModule(schemaContext, typeDefinition);
568 final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition);
569 if (module != null) {
570 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
571 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
572 if (genTOs != null) {
573 returnType = genTOs.get(typedefName);
575 if (returnType == null) {
576 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
577 baseTypeDef, typeDefinition, r, null);
585 * Returns JAVA <code>Type</code> for instances of the type
586 * <code>LeafrefTypeDefinition</code> or
587 * <code>IdentityrefTypeDefinition</code>.
589 * @param typeDefinition
590 * type definition which is converted to JAVA <code>Type</code>
591 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
593 private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
594 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
595 ModuleContext context) {
596 if (typeDefinition instanceof LeafrefTypeDefinition) {
597 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
598 if (isLeafRefSelfReference(leafref, parentNode, schemaContext)) {
599 throw new YangValidationException("Leafref " + leafref.toString() + " is referencing itself, incoming" +
600 " StackOverFlowError detected.");
602 return provideTypeForLeafref(leafref, parentNode, schemaContext, genTypeDefsContextMap, context);
603 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
604 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
605 return provideTypeForIdentityref(idref, schemaContext);
612 * Converts <code>leafrefType</code> to JAVA <code>Type</code>.
614 * The path of <code>leafrefType</code> is followed to find referenced node
615 * and its <code>Type</code> is returned.
618 * leafref type definition for which is the type sought
619 * @return JAVA <code>Type</code> of data schema node which is referenced in
620 * <code>leafrefType</code>
621 * @throws IllegalArgumentException
623 * <li>if <code>leafrefType</code> equal null</li>
624 * <li>if path statement of <code>leafrefType</code> equal null</li>
628 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode,
629 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
630 ModuleContext context) {
632 Type returnType = null;
633 Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
635 Preconditions.checkArgument(leafrefType.getPathStatement() != null,
636 "The Path Statement for Leafref Type Definition cannot be NULL!");
638 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
639 final String strXPath = xpath.toString();
641 if (strXPath != null) {
642 if (strXPath.indexOf('[') == -1) {
643 final Module module = findParentModule(schemaContext, parentNode);
644 Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
646 final SchemaNode dataNode;
647 if (xpath.isAbsolute()) {
648 dataNode = findDataSchemaNode(schemaContext, module, xpath);
650 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
652 Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)",
653 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
655 if (leafContainsEnumDefinition(dataNode)) {
656 returnType = this.referencedTypes.get(dataNode.getPath());
657 } else if (leafListContainsEnumDefinition(dataNode)) {
658 returnType = Types.listTypeFor(this.referencedTypes.get(dataNode.getPath()));
660 returnType = resolveTypeFromDataSchemaNode(dataNode, schemaContext, genTypeDefsContextMap, context);
663 returnType = Types.typeForClass(Object.class);
666 Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)",
667 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
672 * Checks if <code>dataNode</code> is <code>LeafSchemaNode</code> and if it
673 * so then checks if it is of type <code>EnumTypeDefinition</code>.
676 * data schema node for which is checked if it is leaf and if it
678 * @return boolean value
680 * <li>true - if <code>dataNode</code> is leaf of type enumeration</li>
681 * <li>false - other cases</li>
684 private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) {
685 if (dataNode instanceof LeafSchemaNode) {
686 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
687 //CompatUtils is not used here anymore
688 if (leaf.getType() instanceof EnumTypeDefinition) {
696 * Checks if <code>dataNode</code> is <code>LeafListSchemaNode</code> and if
697 * it so then checks if it is of type <code>EnumTypeDefinition</code>.
700 * data schema node for which is checked if it is leaflist and if
702 * @return boolean value
704 * <li>true - if <code>dataNode</code> is leaflist of type
706 * <li>false - other cases</li>
709 private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) {
710 if (dataNode instanceof LeafListSchemaNode) {
711 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
712 if (leafList.getType() instanceof EnumTypeDefinition) {
720 * Converts <code>dataNode</code> to JAVA <code>Type</code>.
723 * contains information about YANG type
724 * @return JAVA <code>Type</code> representation of <code>dataNode</code>
726 private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode, final SchemaContext schemaContext,
727 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
728 Type returnType = null;
729 if (dataNode != null) {
730 if (dataNode instanceof LeafSchemaNode) {
731 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
732 //not using CompatUtils here anymore
733 final TypeDefinition<?> type = leaf.getType();
734 returnType = javaTypeForSchemaDefType(type, leaf, null, schemaContext, genTypeDefsContextMap, context);
735 } else if (dataNode instanceof LeafListSchemaNode) {
736 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
737 returnType = javaTypeForSchemaDefType(leafList.getType(), leafList, null, schemaContext,
738 genTypeDefsContextMap, context);
745 * Seeks for identity reference <code>idref</code> the JAVA
746 * <code>type</code>.<br />
750 * If identy which is referenced via <code>idref</code> has name <b>Idn</b>
751 * then returning type is <b>{@code Class<? extends Idn>}</b></i>
754 * identityref type definition for which JAVA <code>Type</code>
756 * @return JAVA <code>Type</code> of the identity which is refrenced through
759 private static Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref, final SchemaContext schemaContext) {
760 //TODO: incompatibility with Binding spec v2, get first or only one
761 final QName baseIdQName = idref.getIdentities().iterator().next().getQName();
762 final Module module = schemaContext.findModuleByNamespaceAndRevision(baseIdQName.getNamespace(),
763 baseIdQName.getRevision());
764 IdentitySchemaNode identity = null;
765 for (final IdentitySchemaNode id : module.getIdentities()) {
766 if (id.getQName().equals(baseIdQName)) {
770 Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists");
772 final String basePackageName = BindingMapping.getRootPackageName(module);
773 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath
774 (), BindingNamespaceType.Identity);
776 final String genTypeName = JavaIdentifierNormalizer.normalizeSpecificIdentifier(identity.getQName().getLocalName(),
777 JavaIdentifier.CLASS);
779 final Type baseType = Types.typeForClass(Class.class);
780 final Type paramType = Types.wildcardTypeFor(packageName, genTypeName, true, true, null);
781 return Types.parameterizedTypeFor(baseType, paramType);
784 private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto,
785 final Restrictions r, ModuleContext context) {
786 final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName(), context);
787 final GeneratedTransferObject parent = gto.getSuperType();
788 if (parent != null) {
789 gtob.setExtendsType(parent);
791 gtob.setRestrictions(r);
792 for (final GeneratedProperty gp : gto.getProperties()) {
793 final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName());
794 gpb.setValue(gp.getValue());
795 gpb.setReadOnly(gp.isReadOnly());
796 gpb.setAccessModifier(gp.getAccessModifier());
797 gpb.setReturnType(gp.getReturnType());
798 gpb.setFinal(gp.isFinal());
799 gpb.setStatic(gp.isStatic());
801 return gtob.toInstance();
805 * Adds a new property with the name <code>propertyName</code> and with type
806 * <code>type</code> to <code>unonGenTransObject</code>.
808 * @param unionGenTransObject
809 * generated TO to which should be property added
811 * JAVA <code>type</code> of the property which should be added
812 * to <code>unionGentransObject</code>
813 * @param propertyName
814 * string with name of property which should be added to
815 * <code>unionGentransObject</code>
817 private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) {
818 if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
819 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
820 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(propertyName, JavaIdentifier.METHOD));
821 propBuilder.setReturnType(type);
823 unionGenTransObject.addEqualsIdentity(propBuilder);
824 unionGenTransObject.addHashIdentity(propBuilder);
825 unionGenTransObject.addToStringProperty(propBuilder);
830 * Wraps code which handle case when union subtype is also of the type
831 * <code>UnionType</code>.
833 * In this case the new generated TO is created for union subtype (recursive
835 * {@link #provideGeneratedTOBuilderForUnionTypeDef(String, UnionTypeDefinition, String, SchemaNode, SchemaContext, Map, ModuleContext)}
836 * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
837 * <code>parentUnionGenTOBuilder</code> is created property which type is
838 * equal to new generated TO.
840 * @param parentUnionGenTOBuilder
841 * generated TO builder to which is the property with the child
842 * union subtype added
843 * @param basePackageName
844 * string with the name of the module package
845 * @param unionSubtype
846 * type definition which represents union subtype
847 * @return list of generated TO builders. The number of the builders can be
848 * bigger one due to recursive call of
849 * <code>provideGeneratedTOBuildersForUnionTypeDef</code> method.
851 private GeneratedTOBuilder resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
852 final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode,
853 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
854 ModuleContext context) {
856 final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
857 final GeneratedTOBuilder subUnionGenTOBUilder = provideGeneratedTOBuilderForUnionTypeDef(
858 basePackageName, unionSubtype, newTOBuilderName, parentNode, schemaContext, genTypeDefsContextMap,
861 final GeneratedPropertyBuilder propertyBuilder;
862 propertyBuilder = parentUnionGenTOBuilder
863 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
864 propertyBuilder.setReturnType(subUnionGenTOBUilder);
865 parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
866 parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
868 return subUnionGenTOBUilder;
872 * Converts output list of generated TO builders to one TO builder (first
873 * from list) which contains the remaining builders as its enclosing TO.
875 * @param basePackageName
876 * string with name of package to which the module belongs
878 * type definition which should be of type
879 * <code>UnionTypeDefinition</code>
881 * string with name for generated TO
882 * @return generated TO builder with the list of enclosed generated TO
885 public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
886 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
887 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
888 ModuleContext context) {
890 final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
891 typedef, typeDefName, parentNode, schemaContext, genTypeDefsContextMap, context);
892 Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef);
894 final GeneratedTOBuilder resultTOBuilder = builders.remove(0);
895 for (final GeneratedTOBuilder genTOBuilder : builders) {
896 resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
899 final GeneratedPropertyBuilder genPropBuilder;
901 genPropBuilder = resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY).setReadOnly(false);
902 resultTOBuilder.addEqualsIdentity(genPropBuilder);
903 resultTOBuilder.addHashIdentity(genPropBuilder);
904 resultTOBuilder.addToStringProperty(genPropBuilder);
906 provideGeneratedTOBuilderForUnionBuilder(findParentModule(schemaContext, parentNode), resultTOBuilder);
908 return resultTOBuilder;
912 private GeneratedTOBuilder provideGeneratedTOBuilderForUnionBuilder(final Module parentModule,
913 final GeneratedTOBuilder genTOBuilder) {
914 final String outerCls = Types.getOuterClassName(genTOBuilder);
915 final StringBuilder name;
916 if (outerCls != null) {
917 name = new StringBuilder(outerCls);
919 name = new StringBuilder();
921 name.append(genTOBuilder.getName());
922 name.append("Builder");
923 final GeneratedTOBuilderImpl unionBuilder = new GeneratedTOBuilderImpl(getOuterClassPackageName(genTOBuilder),
924 name.toString(), true);
925 unionBuilder.setIsUnionBuilder(true);
927 final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
928 method.setReturnType(genTOBuilder);
929 method.addParameter(Types.STRING, "defaultValue");
930 method.setAccessModifier(AccessModifier.PUBLIC);
931 method.setStatic(true);
933 final Set<Type> types = this.getAdditionalTypes().get(parentModule);
935 this.getAdditionalTypes().put(parentModule,
936 Sets.newHashSet(unionBuilder.toInstance()));
938 types.add(unionBuilder.toInstance());
945 * Wraps code which handle case when union subtype is of the type
946 * <code>ExtendedType</code>.
948 * If TO for this type already exists it is used for the creation of the
949 * property in <code>parentUnionGenTOBuilder</code>. In other case the base
950 * type is used for the property creation.
952 * @param parentUnionGenTOBuilder
953 * generated TO builder in which new property is created
954 * @param unionSubtype
955 * type definition of the <code>ExtendedType</code> type which
956 * represents union subtype
957 * @param regularExpressions
958 * list of strings with the regular expressions
960 * parent Schema Node for Extended Subtype
963 private static void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
964 final TypeDefinition<?> unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode,
965 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
967 final String unionTypeName = unionSubtype.getQName().getLocalName();
968 final Type genTO = findGenTO(unionTypeName, unionSubtype, schemaContext, genTypeDefsContextMap);
970 updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, unionTypeName);
972 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
973 if (unionTypeName.equals(baseType.getQName().getLocalName())) {
974 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
976 if (javaType != null) {
977 updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
980 if (baseType instanceof StringTypeDefinition) {
981 regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype));
987 * Returns string which contains the same value as <code>name</code> but
988 * integer suffix is incremented by one. If <code>name</code> contains no
989 * number suffix then number 1 is added.
992 * string with name of augmented node
993 * @return string with the number suffix incremented by one (or 1 is added)
995 private static String provideAvailableNameForGenTOBuilder(final String name) {
996 final Matcher mtch = NUMBERS_PATTERN.matcher(name);
998 final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1;
999 return name.substring(0, mtch.start()) + newSuffix;
1006 * Searches for generated TO for <code>searchedTypeDef</code> type
1007 * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap}
1009 * @param searchedTypeName
1010 * string with name of <code>searchedTypeDef</code>
1011 * @return generated TO for <code>searchedTypeDef</code> or
1012 * <code>null</code> it it doesn't exist
1014 private static Type findGenTO(final String searchedTypeName, final SchemaNode parentNode,
1015 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
1017 final Module typeModule = findParentModule(schemaContext, parentNode);
1018 if (typeModule != null && typeModule.getName() != null) {
1019 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(typeModule.getName());
1020 final Map<String, Type> genTOs = modulesByDate.get(typeModule.getRevision());
1021 if (genTOs != null) {
1022 return genTOs.get(searchedTypeName);
1029 * Adds enumeration to <code>typeBuilder</code>. The enumeration data are
1030 * taken from <code>enumTypeDef</code>.
1032 * @param enumTypeDef
1033 * enumeration type definition is source of enumeration data for
1034 * <code>typeBuilder</code>
1036 * string with the name of enumeration
1037 * @param typeBuilder
1038 * generated type builder to which is enumeration added
1039 * @return enumeration type which contains enumeration data form
1040 * <code>enumTypeDef</code>
1041 * @throws IllegalArgumentException
1043 * <li>if <code>enumTypeDef</code> equals null</li>
1044 * <li>if enum values of <code>enumTypeDef</code> equal null</li>
1045 * <li>if Q name of <code>enumTypeDef</code> equal null</li>
1046 * <li>if name of <code>enumTypeDef</code> equal null</li>
1047 * <li>if name of <code>typeBuilder</code> equal null</li>
1051 private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef,
1052 final String enumName, final GeneratedTypeBuilderBase<?> typeBuilder, ModuleContext context) {
1053 Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
1054 Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
1055 "Local Name in EnumTypeDefinition QName cannot be NULL!");
1056 Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
1058 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumName, context);
1059 final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
1060 enumBuilder.setDescription(enumTypedefDescription);
1061 enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
1062 return enumBuilder.toInstance(enumBuilder);
1065 private static boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode,
1066 final SchemaContext schemaContext) {
1067 final SchemaNode leafRefValueNode;
1068 final RevisionAwareXPath leafRefXPath = leafref.getPathStatement();
1069 final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl(leafRefXPath.toString()
1070 .replaceAll("\\[(.*?)\\]", ""), leafRefXPath.isAbsolute());
1072 ///// skip leafrefs in augments - they're checked once augments are resolved
1073 final Iterator<QName> iterator = parentNode.getPath().getPathFromRoot().iterator();
1074 boolean isAugmenting = false;
1075 DataNodeContainer current = null;
1076 DataSchemaNode dataChildByName;
1078 while (iterator.hasNext() && !isAugmenting) {
1079 final QName next = iterator.next();
1080 if (current == null) {
1081 dataChildByName = schemaContext.getDataChildByName(next);
1083 dataChildByName = current.getDataChildByName(next);
1085 if (dataChildByName != null) {
1086 isAugmenting = dataChildByName.isAugmenting();
1090 if (dataChildByName instanceof DataNodeContainer) {
1091 current = (DataNodeContainer) dataChildByName;
1099 final Module parentModule = getParentModule(parentNode, schemaContext);
1100 if (!leafRefStrippedXPath.isAbsolute()) {
1101 leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
1102 parentNode, leafRefStrippedXPath);
1104 leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath);
1106 return (leafRefValueNode != null) && leafRefValueNode.equals(parentNode);