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.yang.types.TypeGenHelper.addStringRegExAsConstant;
13 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.baseTypeDefForExtendedType;
14 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.getAllTypedefs;
15 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.getParentModule;
16 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.makeSerializable;
17 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.provideGeneratedTOFromExtendedType;
18 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.provideTypeForEnum;
19 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.resolveRegExpressionsFromTypedef;
20 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.sortTypeDefinitionAccordingDepth;
21 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.wrapJavaTypeIntoTO;
22 import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.getRootPackageName;
23 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
24 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
25 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
27 import com.google.common.annotations.Beta;
28 import com.google.common.base.Preconditions;
29 import com.google.common.base.Strings;
30 import com.google.common.collect.Sets;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.Date;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
39 import java.util.regex.Matcher;
40 import java.util.regex.Pattern;
41 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
42 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
43 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
44 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
45 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
46 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
47 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
48 import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
49 import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
50 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty;
51 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
52 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
53 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
54 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
55 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
56 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
57 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilderBase;
58 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
59 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
60 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
61 import org.opendaylight.yangtools.yang.common.QName;
62 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
63 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
64 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
65 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
66 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
67 import org.opendaylight.yangtools.yang.model.api.Module;
68 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
69 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
70 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
71 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
72 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
73 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
74 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
75 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
76 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
77 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
78 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
79 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
80 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
81 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
82 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
83 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
88 public final class TypeProviderImpl implements TypeProvider {
90 private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
91 private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
94 * Contains the schema data red from YANG files.
96 private final SchemaContext schemaContext;
99 * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
101 private final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
104 * Map which maps schema paths to JAVA <code>Type</code>.
106 private final Map<SchemaPath, Type> referencedTypes;
109 * Map for additional types e.g unions
111 private final Map<Module, Set<Type>> additionalTypes;
114 * Creates new instance of class <code>TypeProviderImpl</code>.
116 * @param schemaContext
117 * contains the schema data red from YANG files
118 * @throws IllegalArgumentException
119 * if <code>schemaContext</code> equal null.
121 public TypeProviderImpl(final SchemaContext schemaContext) {
122 this.schemaContext = schemaContext;
123 this.genTypeDefsContextMap = new HashMap<>();
124 this.referencedTypes = new HashMap<>();
125 this.additionalTypes = new HashMap<>();
126 resolveTypeDefsFromContext(schemaContext, this.genTypeDefsContextMap, this.additionalTypes);
130 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode) {
131 return javaTypeForSchemaDefinitionType(type, parentNode, null);
135 * Converts schema definition type <code>typeDefinition</code> to JAVA
139 * type definition which is converted to JAVA type
140 * @throws IllegalArgumentException
142 * <li>if <code>typeDefinition</code> equal null</li>
143 * <li>if QName of <code>typeDefinition</code> equal null</li>
144 * <li>if name of <code>typeDefinition</code> equal null</li>
148 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode, final Restrictions restrictions) {
149 return javaTypeForSchemaDefType(type, parentNode, restrictions, this.schemaContext, this.genTypeDefsContextMap);
153 public String getTypeDefaultConstruction(final LeafSchemaNode node) {
158 public String getConstructorPropertyName(final SchemaNode node) {
163 public String getParamNameFromType(final TypeDefinition<?> type) {
167 public Map<String, Map<Date, Map<String, Type>>> getGenTypeDefsContextMap() {
168 return this.genTypeDefsContextMap;
172 * Passes through all modules and through all its type definitions and
173 * convert it to generated types.
175 * The modules are firstly sorted by mutual dependencies. The modules are
176 * sequentially passed. All type definitions of a module are at the
177 * beginning sorted so that type definition with less amount of references
178 * to other type definition are processed first.<br />
179 * For each module is created mapping record in the map
180 * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap}
181 * which map current module name to the map which maps type names to
182 * returned types (generated types).
185 private void resolveTypeDefsFromContext(final SchemaContext schemaContext, final Map<String, Map<Date, Map<String,
186 Type>>> genTypeDefsContextMap, final Map<Module, Set<Type>> additionalTypes) {
188 final Set<Module> modules = schemaContext.getModules();
189 Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
190 final Module[] modulesArray = new Module[modules.size()];
192 for (final Module modul : modules) {
193 modulesArray[i++] = modul;
195 final List<Module> modulesSortedByDependency = org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort
198 for (final Module module : modulesSortedByDependency) {
199 Map<Date, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
200 if (dateTypeMap == null) {
201 dateTypeMap = new HashMap<>();
203 dateTypeMap.put(module.getRevision(), Collections.emptyMap());
204 genTypeDefsContextMap.put(module.getName(), dateTypeMap);
207 modulesSortedByDependency.stream().filter(module -> module != null).forEach(module -> {
208 final String basePackageName = getRootPackageName(module);
209 final List<TypeDefinition<?>> typeDefinitions = getAllTypedefs(module);
210 final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
211 if (listTypeDefinitions != null) {
212 for (final TypeDefinition<?> typedef : listTypeDefinitions) {
213 typedefToGeneratedType(basePackageName, module, typedef, genTypeDefsContextMap,
214 additionalTypes, schemaContext);
221 * Converts <code>typeDefinition</code> to concrete JAVA <code>Type</code>.
223 * @param typeDefinition
224 * type definition which should be converted to JAVA
226 * @return JAVA <code>Type</code> which represents
227 * <code>typeDefinition</code>
228 * @throws IllegalArgumentException
230 * <li>if <code>typeDefinition</code> equal null</li>
231 * <li>if Q name of <code>typeDefinition</code></li>
232 * <li>if name of <code>typeDefinition</code></li>
235 public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
236 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
237 Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
238 "Type Definitions Local Name cannot be NULL!");
240 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
241 if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
242 final Module module = findParentModule(this.schemaContext, parentNode);
244 if (module != null) {
245 final Map<Date, Map<String, Type>> modulesByDate = this.genTypeDefsContextMap.get(module.getName());
246 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
247 if (genTOs != null) {
248 return genTOs.get(typeDefinition.getQName().getLocalName());
256 * Puts <code>refType</code> to map with key <code>refTypePath</code>
259 * schema path used as the map key
261 * type which represents the map value
262 * @throws IllegalArgumentException
264 * <li>if <code>refTypePath</code> equal null</li>
265 * <li>if <code>refType</code> equal null</li>
269 public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
270 Preconditions.checkArgument(refTypePath != null,
271 "Path reference of Enumeration Type Definition cannot be NULL!");
272 Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!");
273 this.referencedTypes.put(refTypePath, refType);
277 * Converts <code>typeDef</code> which should be of the type
278 * <code>BitsTypeDefinition</code> to <code>GeneratedTOBuilder</code>.
280 * All the bits of the typeDef are added to returning generated TO as
283 * @param basePackageName
284 * string with name of package to which the module belongs
286 * type definition from which is the generated TO builder created
288 * string with the name for generated TO builder
289 * @return generated TO builder which represents <code>typeDef</code>
290 * @throws IllegalArgumentException
292 * <li>if <code>typeDef</code> equals null</li>
293 * <li>if <code>basePackageName</code> equals null</li>
296 @SuppressWarnings({ "rawtypes", "unchecked" })
297 public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, final
298 TypeDefinition<?> typeDef, final String typeDefName, final String moduleName) {
300 Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
301 Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
303 if (typeDef instanceof BitsTypeDefinition) {
304 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
306 final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName);
307 final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
309 genTOBuilder.setDescription(typedefDescription);
310 genTOBuilder.setReference(typeDef.getReference());
311 genTOBuilder.setSchemaPath((List) typeDef.getPath().getPathFromRoot());
312 genTOBuilder.setModuleName(moduleName);
313 genTOBuilder.setBaseType(typeDef);
315 final List<Bit> bitList = bitsTypeDefinition.getBits();
316 GeneratedPropertyBuilder genPropertyBuilder;
317 for (final Bit bit : bitList) {
318 final String name = bit.getName();
320 genTOBuilder.addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
321 genPropertyBuilder.setReadOnly(true);
322 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
324 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
325 genTOBuilder.addHashIdentity(genPropertyBuilder);
326 genTOBuilder.addToStringProperty(genPropertyBuilder);
335 * Converts <code>typedef</code> to generated TO with
336 * <code>typeDefName</code>. Every union type from <code>typedef</code> is
337 * added to generated TO builder as property.
339 * @param basePackageName
340 * string with name of package to which the module belongs
342 * type definition which should be of type
343 * <code>UnionTypeDefinition</code>
345 * string with name for generated TO
346 * @return generated TO builder which represents <code>typedef</code>
347 * @throws NullPointerException
349 * <li>if <code>basePackageName</code> is null</li>
350 * <li>if <code>typedef</code> is null</li>
351 * <li>if QName of <code>typedef</code> is null</li>
354 @SuppressWarnings({ "rawtypes", "unchecked" })
355 public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
356 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode, final SchemaContext
357 schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
358 Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
359 Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
360 Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
362 final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
363 final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
364 final Module module = findParentModule(schemaContext, parentNode);
366 final GeneratedTOBuilderImpl unionGenTOBuilder;
367 if (typeDefName != null && !typeDefName.isEmpty()) {
368 unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName);
369 final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
370 unionGenTOBuilder.setDescription(typedefDescription);
371 unionGenTOBuilder.setReference(typedef.getReference());
372 unionGenTOBuilder.setSchemaPath((List) typedef.getPath().getPathFromRoot());
373 unionGenTOBuilder.setModuleName(module.getName());
375 unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef, module.getName());
378 generatedTOBuilders.add(unionGenTOBuilder);
379 unionGenTOBuilder.setIsUnion(true);
380 final List<String> regularExpressions = new ArrayList<>();
381 for (final TypeDefinition<?> unionType : unionTypes) {
382 final String unionTypeName = unionType.getQName().getLocalName();
383 if (unionType.getBaseType() != null) {
384 resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, regularExpressions,
385 parentNode, schemaContext, genTypeDefsContextMap);
386 } else if (unionType instanceof UnionTypeDefinition) {
387 generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
388 basePackageName, parentNode, schemaContext, genTypeDefsContextMap));
389 } else if (unionType instanceof EnumTypeDefinition) {
390 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
391 unionTypeName, unionGenTOBuilder);
392 updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
394 final Type javaType = javaTypeForSchemaDefType(unionType, parentNode, null, schemaContext,
395 genTypeDefsContextMap);
396 updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
399 if (!regularExpressions.isEmpty()) {
400 addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
403 //storeGenTO(typedef, unionGenTOBuilder, parentNode);
405 return generatedTOBuilders;
408 public Map<Module, Set<Type>> getAdditionalTypes() {
409 return this.additionalTypes;
412 public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) {
413 if (!Strings.isNullOrEmpty(units)) {
414 to.addConstant(Types.STRING, "Units", "\"" + units + "\"");
415 final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
416 prop.setReturnType(Types.STRING);
417 to.addToStringProperty(prop);
421 private Type javaTypeForSchemaDefType(final TypeDefinition<?> typeDefinition, final SchemaNode
422 parentNode, final Restrictions r, final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
423 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
424 final String typedefName = typeDefinition.getQName().getLocalName();
425 Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
427 // Deal with base types
428 if (typeDefinition.getBaseType() == null) {
429 // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type
430 // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates
431 // a base type which holds these constraints.
432 if (typeDefinition instanceof DecimalTypeDefinition) {
433 final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode, r);
439 // Deal with leafrefs/identityrefs
440 Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode, schemaContext, genTypeDefsContextMap);
445 ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode);
447 LOG.debug("Failed to resolve Java type for {}", typeDefinition);
453 Type returnType = javaTypeForExtendedType(typeDefinition, schemaContext, genTypeDefsContextMap);
454 if (r != null && returnType instanceof GeneratedTransferObject) {
455 final GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
456 final Module module = findParentModule(schemaContext, parentNode);
457 final String basePackageName = BindingMapping.getRootPackageName(module);
458 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typeDefinition
459 .getPath(), BindingNamespaceType.Typedef);
460 final String genTOName = JavaIdentifierNormalizer.normalizeClassIdentifier(packageName, typedefName);
461 final String name = packageName + "." + genTOName;
462 if (!(returnType.getFullyQualifiedName().equals(name))) {
463 returnType = shadedTOWithRestrictions(gto, r);
471 * @param basePackageName
472 * string with name of package to which the module belongs
474 * string with the name of the module for to which the
475 * <code>typedef</code> belongs
477 * type definition of the node for which should be creted JAVA
478 * <code>Type</code> (usually generated TO)
479 * @return JAVA <code>Type</code> representation of <code>typedef</code> or
480 * <code>null</code> value if <code>basePackageName</code> or
481 * <code>modulName</code> or <code>typedef</code> or Q name of
482 * <code>typedef</code> equals <code>null</code>
484 private Type typedefToGeneratedType(final String basePackageName, final Module module, final
485 TypeDefinition<?> typedef, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, final Map<Module,
486 Set<Type>> additionalTypes, final SchemaContext schemaContext) {
487 final String moduleName = module.getName();
488 final Date moduleRevision = module.getRevision();
489 if ((basePackageName != null) && (moduleName != null) && (typedef != null)) {
490 final String typedefName = typedef.getQName().getLocalName();
491 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
492 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
493 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
495 if (innerTypeDefinition.getBaseType() != null) {
496 returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName,
497 module.getName(), schemaContext, genTypeDefsContextMap);
498 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
499 final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
500 (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef, schemaContext, genTypeDefsContextMap);
501 genTOBuilder.setTypedef(true);
502 genTOBuilder.setIsUnion(true);
503 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
504 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
505 returnType = genTOBuilder.toInstance();
507 final GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(),
508 genTOBuilder.getName() + "Builder");
509 unionBuilder.setIsUnionBuilder(true);
510 final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
511 method.setReturnType(returnType);
512 method.addParameter(Types.STRING, "defaultValue");
513 method.setAccessModifier(AccessModifier.PUBLIC);
514 method.setStatic(true);
515 Set<Type> types = additionalTypes.get(module);
517 types = Sets.newHashSet(unionBuilder.toInstance());
518 additionalTypes.put(module, types);
520 types.add(unionBuilder.toInstance());
522 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
523 // enums are automatically Serializable
524 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
525 // TODO units for typedef enum
526 returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef, schemaContext);
527 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
528 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
529 final GeneratedTOBuilder genTOBuilder =
530 provideGeneratedTOBuilderForBitsTypeDefinition(
531 basePackageName, bitsTypeDefinition, typedefName, module.getName());
532 genTOBuilder.setTypedef(true);
533 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
534 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
535 returnType = genTOBuilder.toInstance();
537 final Type javaType = javaTypeForSchemaDefType(innerTypeDefinition, typedef, null,
538 schemaContext, genTypeDefsContextMap);
539 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName());
541 if (returnType != null) {
542 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
543 Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
544 if (typeMap != null) {
545 if (typeMap.isEmpty()) {
546 typeMap = new HashMap<>(4);
547 modulesByDate.put(moduleRevision, typeMap);
549 typeMap.put(typedefName, returnType);
559 * Returns JAVA <code>Type</code> for instances of the type
560 * <code>ExtendedType</code>.
562 * @param typeDefinition
563 * type definition which is converted to JAVA <code>Type</code>
564 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
566 private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition, final SchemaContext
567 schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
569 final String typedefName = typeDefinition.getQName().getLocalName();
570 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
571 Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition, schemaContext, genTypeDefsContextMap);
572 if (returnType == null) {
573 if (baseTypeDef instanceof EnumTypeDefinition) {
574 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
575 returnType = provideTypeForEnum(enumTypeDef, typedefName, typeDefinition, schemaContext);
577 final Module module = findParentModule(schemaContext, typeDefinition);
578 final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition);
579 if (module != null) {
580 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
581 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
582 if (genTOs != null) {
583 returnType = genTOs.get(typedefName);
585 if (returnType == null) {
586 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
587 baseTypeDef, typeDefinition, r);
596 * Returns JAVA <code>Type</code> for instances of the type
597 * <code>LeafrefTypeDefinition</code> or
598 * <code>IdentityrefTypeDefinition</code>.
600 * @param typeDefinition
601 * type definition which is converted to JAVA <code>Type</code>
602 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
604 private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
605 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
606 if (typeDefinition instanceof LeafrefTypeDefinition) {
607 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
608 if (isLeafRefSelfReference(leafref, parentNode, schemaContext)) {
609 throw new YangValidationException("Leafref " + leafref.toString() + " is referencing itself, incoming" +
610 " StackOverFlowError detected.");
612 return provideTypeForLeafref(leafref, parentNode, schemaContext, genTypeDefsContextMap);
613 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
614 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
615 return provideTypeForIdentityref(idref, schemaContext);
622 * Converts <code>leafrefType</code> to JAVA <code>Type</code>.
624 * The path of <code>leafrefType</code> is followed to find referenced node
625 * and its <code>Type</code> is returned.
628 * leafref type definition for which is the type sought
629 * @return JAVA <code>Type</code> of data schema node which is referenced in
630 * <code>leafrefType</code>
631 * @throws IllegalArgumentException
633 * <li>if <code>leafrefType</code> equal null</li>
634 * <li>if path statement of <code>leafrefType</code> equal null</li>
638 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode,
639 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
641 Type returnType = null;
642 Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
644 Preconditions.checkArgument(leafrefType.getPathStatement() != null,
645 "The Path Statement for Leafref Type Definition cannot be NULL!");
647 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
648 final String strXPath = xpath.toString();
650 if (strXPath != null) {
651 if (strXPath.indexOf('[') == -1) {
652 final Module module = findParentModule(schemaContext, parentNode);
653 Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
655 final SchemaNode dataNode;
656 if (xpath.isAbsolute()) {
657 dataNode = findDataSchemaNode(schemaContext, module, xpath);
659 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
661 Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)",
662 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
664 if (leafContainsEnumDefinition(dataNode)) {
665 returnType = this.referencedTypes.get(dataNode.getPath());
666 } else if (leafListContainsEnumDefinition(dataNode)) {
667 returnType = Types.listTypeFor(this.referencedTypes.get(dataNode.getPath()));
669 returnType = resolveTypeFromDataSchemaNode(dataNode, schemaContext, genTypeDefsContextMap);
672 returnType = Types.typeForClass(Object.class);
675 Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)",
676 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
681 * Checks if <code>dataNode</code> is <code>LeafSchemaNode</code> and if it
682 * so then checks if it is of type <code>EnumTypeDefinition</code>.
685 * data schema node for which is checked if it is leaf and if it
687 * @return boolean value
689 * <li>true - if <code>dataNode</code> is leaf of type enumeration</li>
690 * <li>false - other cases</li>
693 private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) {
694 if (dataNode instanceof LeafSchemaNode) {
695 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
696 //CompatUtils is not used here anymore
697 if (leaf.getType() instanceof EnumTypeDefinition) {
705 * Checks if <code>dataNode</code> is <code>LeafListSchemaNode</code> and if
706 * it so then checks if it is of type <code>EnumTypeDefinition</code>.
709 * data schema node for which is checked if it is leaflist and if
711 * @return boolean value
713 * <li>true - if <code>dataNode</code> is leaflist of type
715 * <li>false - other cases</li>
718 private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) {
719 if (dataNode instanceof LeafListSchemaNode) {
720 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
721 if (leafList.getType() instanceof EnumTypeDefinition) {
729 * Converts <code>dataNode</code> to JAVA <code>Type</code>.
732 * contains information about YANG type
733 * @return JAVA <code>Type</code> representation of <code>dataNode</code>
735 private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode, final SchemaContext schemaContext,
736 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
737 Type returnType = null;
738 if (dataNode != null) {
739 if (dataNode instanceof LeafSchemaNode) {
740 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
741 //not using CompatUtils here anymore
742 final TypeDefinition<?> type = leaf.getType();
743 returnType = javaTypeForSchemaDefType(type, leaf, null, schemaContext, genTypeDefsContextMap);
744 } else if (dataNode instanceof LeafListSchemaNode) {
745 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
746 returnType = javaTypeForSchemaDefType(leafList.getType(), leafList, null, schemaContext, genTypeDefsContextMap);
753 * Seeks for identity reference <code>idref</code> the JAVA
754 * <code>type</code>.<br />
758 * If identy which is referenced via <code>idref</code> has name <b>Idn</b>
759 * then returning type is <b>{@code Class<? extends Idn>}</b></i>
762 * identityref type definition for which JAVA <code>Type</code>
764 * @return JAVA <code>Type</code> of the identity which is refrenced through
767 private static Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref, final SchemaContext schemaContext) {
768 //TODO: incompatibility with Binding spec v2, get first or only one
769 final QName baseIdQName = idref.getIdentities().iterator().next().getQName();
770 final Module module = schemaContext.findModuleByNamespaceAndRevision(baseIdQName.getNamespace(),
771 baseIdQName.getRevision());
772 IdentitySchemaNode identity = null;
773 for (final IdentitySchemaNode id : module.getIdentities()) {
774 if (id.getQName().equals(baseIdQName)) {
778 Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists");
780 final String basePackageName = BindingMapping.getRootPackageName(module);
781 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath
782 (), BindingNamespaceType.Typedef);
783 final String genTypeName =
784 JavaIdentifierNormalizer.normalizeClassIdentifier(packageName, identity.getQName().getLocalName());
786 final Type baseType = Types.typeForClass(Class.class);
787 final Type paramType = Types.wildcardTypeFor(packageName, genTypeName);
788 return Types.parameterizedTypeFor(baseType, paramType);
792 * Converts <code>typedef</code> to the generated TO builder.
794 * @param basePackageName
795 * string with name of package to which the module belongs
797 * type definition from which is the generated TO builder created
798 * @return generated TO builder which contains data from
799 * <code>typedef</code> and <code>basePackageName</code>
801 @SuppressWarnings({ "rawtypes", "unchecked" })
802 private static GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef, final String moduleName) {
804 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typedef.getPath
805 (), BindingNamespaceType.Typedef);
806 final String typeDefTOName = typedef.getQName().getLocalName();
808 if ((packageName != null) && (typeDefTOName != null)) {
809 final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, typeDefTOName);
810 final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
812 newType.setDescription(typedefDescription);
813 newType.setReference(typedef.getReference());
814 newType.setSchemaPath((List) typedef.getPath().getPathFromRoot());
815 newType.setModuleName(moduleName);
822 private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto, final Restrictions r) {
823 final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName());
824 final GeneratedTransferObject parent = gto.getSuperType();
825 if (parent != null) {
826 gtob.setExtendsType(parent);
828 gtob.setRestrictions(r);
829 for (final GeneratedProperty gp : gto.getProperties()) {
830 final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName());
831 gpb.setValue(gp.getValue());
832 gpb.setReadOnly(gp.isReadOnly());
833 gpb.setAccessModifier(gp.getAccessModifier());
834 gpb.setReturnType(gp.getReturnType());
835 gpb.setFinal(gp.isFinal());
836 gpb.setStatic(gp.isStatic());
838 return gtob.toInstance();
842 * Adds a new property with the name <code>propertyName</code> and with type
843 * <code>type</code> to <code>unonGenTransObject</code>.
845 * @param unionGenTransObject
846 * generated TO to which should be property added
848 * JAVA <code>type</code> of the property which should be added
849 * to <code>unionGentransObject</code>
850 * @param propertyName
851 * string with name of property which should be added to
852 * <code>unionGentransObject</code>
854 private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) {
855 if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
856 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
857 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(propertyName, JavaIdentifier.METHOD));
858 propBuilder.setReturnType(type);
860 unionGenTransObject.addEqualsIdentity(propBuilder);
861 unionGenTransObject.addHashIdentity(propBuilder);
862 unionGenTransObject.addToStringProperty(propBuilder);
867 * Wraps code which handle case when union subtype is also of the type
868 * <code>UnionType</code>.
870 * In this case the new generated TO is created for union subtype (recursive
872 * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, UnionTypeDefinition,
873 * String, SchemaNode, SchemaContext, Map)}
874 * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
875 * <code>parentUnionGenTOBuilder</code> is created property which type is
876 * equal to new generated TO.
878 * @param parentUnionGenTOBuilder
879 * generated TO builder to which is the property with the child
880 * union subtype added
881 * @param basePackageName
882 * string with the name of the module package
883 * @param unionSubtype
884 * type definition which represents union subtype
885 * @return list of generated TO builders. The number of the builders can be
886 * bigger one due to recursive call of
887 * <code>provideGeneratedTOBuildersForUnionTypeDef</code> method.
889 private List<GeneratedTOBuilder> resolveUnionSubtypeAsUnion(final GeneratedTOBuilder
890 parentUnionGenTOBuilder, final UnionTypeDefinition unionSubtype, final String basePackageName,
891 final SchemaNode parentNode, final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
893 final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
894 final List<GeneratedTOBuilder> subUnionGenTOBUilders = provideGeneratedTOBuildersForUnionTypeDef(
895 basePackageName, unionSubtype, newTOBuilderName, parentNode, schemaContext, genTypeDefsContextMap);
897 final GeneratedPropertyBuilder propertyBuilder;
898 propertyBuilder = parentUnionGenTOBuilder
899 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
900 propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0));
901 parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
902 parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
904 return subUnionGenTOBUilders;
908 * Converts output list of generated TO builders to one TO builder (first
909 * from list) which contains the remaining builders as its enclosing TO.
911 * @param basePackageName
912 * string with name of package to which the module belongs
914 * type definition which should be of type
915 * <code>UnionTypeDefinition</code>
917 * string with name for generated TO
918 * @return generated TO builder with the list of enclosed generated TO
921 private GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
922 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode, final SchemaContext
923 schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
925 final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
926 typedef, typeDefName, parentNode, schemaContext, genTypeDefsContextMap);
927 Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef);
929 final GeneratedTOBuilder resultTOBuilder = builders.remove(0);
930 for (final GeneratedTOBuilder genTOBuilder : builders) {
931 resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
934 resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY);
935 return resultTOBuilder;
939 * Wraps code which handle case when union subtype is of the type
940 * <code>ExtendedType</code>.
942 * If TO for this type already exists it is used for the creation of the
943 * property in <code>parentUnionGenTOBuilder</code>. In other case the base
944 * type is used for the property creation.
946 * @param parentUnionGenTOBuilder
947 * generated TO builder in which new property is created
948 * @param unionSubtype
949 * type definition of the <code>ExtendedType</code> type which
950 * represents union subtype
951 * @param regularExpressions
952 * list of strings with the regular expressions
954 * parent Schema Node for Extended Subtype
957 private static void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, final
958 TypeDefinition<?> unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode,
959 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
961 final String unionTypeName = unionSubtype.getQName().getLocalName();
962 final Type genTO = findGenTO(unionTypeName, unionSubtype, schemaContext, genTypeDefsContextMap);
964 updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, genTO.getName());
966 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
967 if (unionTypeName.equals(baseType.getQName().getLocalName())) {
968 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
970 if (javaType != null) {
971 updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
974 if (baseType instanceof StringTypeDefinition) {
975 regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype));
981 * Returns string which contains the same value as <code>name</code> but
982 * integer suffix is incremented by one. If <code>name</code> contains no
983 * number suffix then number 1 is added.
986 * string with name of augmented node
987 * @return string with the number suffix incremented by one (or 1 is added)
989 private static String provideAvailableNameForGenTOBuilder(final String name) {
990 final Matcher mtch = NUMBERS_PATTERN.matcher(name);
992 final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1;
993 return name.substring(0, mtch.start()) + newSuffix;
1000 * Searches for generated TO for <code>searchedTypeDef</code> type
1001 * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap}
1003 * @param searchedTypeName
1004 * string with name of <code>searchedTypeDef</code>
1005 * @return generated TO for <code>searchedTypeDef</code> or
1006 * <code>null</code> it it doesn't exist
1008 private static Type findGenTO(final String searchedTypeName, final SchemaNode parentNode,
1009 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
1011 final Module typeModule = findParentModule(schemaContext, parentNode);
1012 if (typeModule != null && typeModule.getName() != null) {
1013 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(typeModule.getName());
1014 final Map<String, Type> genTOs = modulesByDate.get(typeModule.getRevision());
1015 if (genTOs != null) {
1016 return genTOs.get(searchedTypeName);
1023 * Adds enumeration to <code>typeBuilder</code>. The enumeration data are
1024 * taken from <code>enumTypeDef</code>.
1026 * @param enumTypeDef
1027 * enumeration type definition is source of enumeration data for
1028 * <code>typeBuilder</code>
1030 * string with the name of enumeration
1031 * @param typeBuilder
1032 * generated type builder to which is enumeration added
1033 * @return enumeration type which contains enumeration data form
1034 * <code>enumTypeDef</code>
1035 * @throws IllegalArgumentException
1037 * <li>if <code>enumTypeDef</code> equals null</li>
1038 * <li>if enum values of <code>enumTypeDef</code> equal null</li>
1039 * <li>if Q name of <code>enumTypeDef</code> equal null</li>
1040 * <li>if name of <code>enumTypeDef</code> equal null</li>
1041 * <li>if name of <code>typeBuilder</code> equal null</li>
1045 private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilderBase<?> typeBuilder) {
1046 Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
1047 Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
1048 "Local Name in EnumTypeDefinition QName cannot be NULL!");
1049 Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
1051 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumName);
1052 final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
1053 enumBuilder.setDescription(enumTypedefDescription);
1054 enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
1055 return enumBuilder.toInstance(enumBuilder);
1058 private static boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode,
1059 final SchemaContext schemaContext) {
1060 final SchemaNode leafRefValueNode;
1061 final RevisionAwareXPath leafRefXPath = leafref.getPathStatement();
1062 final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl(leafRefXPath.toString()
1063 .replaceAll("\\[(.*?)\\]", ""), leafRefXPath.isAbsolute());
1065 ///// skip leafrefs in augments - they're checked once augments are resolved
1066 final Iterator<QName> iterator = parentNode.getPath().getPathFromRoot().iterator();
1067 boolean isAugmenting = false;
1068 DataNodeContainer current = null;
1069 DataSchemaNode dataChildByName;
1071 while (iterator.hasNext() && !isAugmenting) {
1072 final QName next = iterator.next();
1073 if (current == null) {
1074 dataChildByName = schemaContext.getDataChildByName(next);
1076 dataChildByName = current.getDataChildByName(next);
1078 if (dataChildByName != null) {
1079 isAugmenting = dataChildByName.isAugmenting();
1083 if (dataChildByName instanceof DataNodeContainer) {
1084 current = (DataNodeContainer) dataChildByName;
1092 final Module parentModule = getParentModule(parentNode, schemaContext);
1093 if (!leafRefStrippedXPath.isAbsolute()) {
1094 leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
1095 parentNode, leafRefStrippedXPath);
1097 leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath);
1099 return (leafRefValueNode != null) && leafRefValueNode.equals(parentNode);