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.spi.TypeProvider;
44 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
45 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
46 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
47 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
48 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
49 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
50 import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
51 import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
52 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty;
53 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
54 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
55 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
56 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
57 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
58 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
59 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilderBase;
60 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
61 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
62 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
63 import org.opendaylight.yangtools.yang.common.QName;
64 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
65 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
66 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
67 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
68 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
69 import org.opendaylight.yangtools.yang.model.api.Module;
70 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
71 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
72 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
73 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
74 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
75 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
76 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
77 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
78 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
79 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
80 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
81 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
82 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
83 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
84 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
85 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
86 import org.slf4j.Logger;
87 import org.slf4j.LoggerFactory;
90 public final class TypeProviderImpl implements TypeProvider {
92 private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
93 private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
96 * Contains the schema data red from YANG files.
98 private final SchemaContext schemaContext;
101 * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
103 private final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
106 * Map which maps schema paths to JAVA <code>Type</code>.
108 private final Map<SchemaPath, Type> referencedTypes;
111 * Map for additional types e.g unions
113 private final Map<Module, Set<Type>> additionalTypes;
116 * Creates new instance of class <code>TypeProviderImpl</code>.
118 * @param schemaContext
119 * contains the schema data red from YANG files
120 * @throws IllegalArgumentException
121 * if <code>schemaContext</code> equal null.
123 public TypeProviderImpl(final SchemaContext schemaContext) {
124 this.schemaContext = schemaContext;
125 this.genTypeDefsContextMap = new HashMap<>();
126 this.referencedTypes = new HashMap<>();
127 this.additionalTypes = new HashMap<>();
128 resolveTypeDefsFromContext(schemaContext, this.genTypeDefsContextMap, this.additionalTypes);
132 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode) {
133 return javaTypeForSchemaDefinitionType(type, parentNode, null);
137 * Converts schema definition type <code>typeDefinition</code> to JAVA
141 * type definition which is converted to JAVA type
142 * @throws IllegalArgumentException
144 * <li>if <code>typeDefinition</code> equal null</li>
145 * <li>if QName of <code>typeDefinition</code> equal null</li>
146 * <li>if name of <code>typeDefinition</code> equal null</li>
150 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode, final Restrictions restrictions) {
151 return javaTypeForSchemaDefType(type, parentNode, restrictions, this.schemaContext, this.genTypeDefsContextMap);
155 public String getTypeDefaultConstruction(final LeafSchemaNode node) {
160 public String getConstructorPropertyName(final SchemaNode node) {
165 public String getParamNameFromType(final TypeDefinition<?> type) {
169 public Map<String, Map<Date, Map<String, Type>>> getGenTypeDefsContextMap() {
170 return this.genTypeDefsContextMap;
174 * Passes through all modules and through all its type definitions and
175 * convert it to generated types.
177 * The modules are firstly sorted by mutual dependencies. The modules are
178 * sequentially passed. All type definitions of a module are at the
179 * beginning sorted so that type definition with less amount of references
180 * to other type definition are processed first.<br />
181 * For each module is created mapping record in the map
182 * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap}
183 * which map current module name to the map which maps type names to
184 * returned types (generated types).
187 private void resolveTypeDefsFromContext(final SchemaContext schemaContext, final Map<String, Map<Date, Map<String,
188 Type>>> genTypeDefsContextMap, final Map<Module, Set<Type>> additionalTypes) {
190 final Set<Module> modules = schemaContext.getModules();
191 Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
192 final Module[] modulesArray = new Module[modules.size()];
194 for (final Module modul : modules) {
195 modulesArray[i++] = modul;
197 final List<Module> modulesSortedByDependency = org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort
200 for (final Module module : modulesSortedByDependency) {
201 Map<Date, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
202 if (dateTypeMap == null) {
203 dateTypeMap = new HashMap<>();
205 dateTypeMap.put(module.getRevision(), Collections.emptyMap());
206 genTypeDefsContextMap.put(module.getName(), dateTypeMap);
209 modulesSortedByDependency.stream().filter(module -> module != null).forEach(module -> {
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);
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, final
301 TypeDefinition<?> typeDef, final String typeDefName, final String moduleName) {
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, true, false);
310 final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
312 genTOBuilder.setDescription(typedefDescription);
313 genTOBuilder.setReference(typeDef.getReference());
314 genTOBuilder.setSchemaPath((List) typeDef.getPath().getPathFromRoot());
315 genTOBuilder.setModuleName(moduleName);
316 genTOBuilder.setBaseType(typeDef);
318 final List<Bit> bitList = bitsTypeDefinition.getBits();
319 GeneratedPropertyBuilder genPropertyBuilder;
320 for (final Bit bit : bitList) {
321 final String name = bit.getName();
323 genTOBuilder.addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
324 genPropertyBuilder.setReadOnly(true);
325 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
327 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
328 genTOBuilder.addHashIdentity(genPropertyBuilder);
329 genTOBuilder.addToStringProperty(genPropertyBuilder);
338 * Converts <code>typedef</code> to generated TO with
339 * <code>typeDefName</code>. Every union type from <code>typedef</code> is
340 * added to generated TO builder as property.
342 * @param basePackageName
343 * string with name of package to which the module belongs
345 * type definition which should be of type
346 * <code>UnionTypeDefinition</code>
348 * string with name for generated TO
349 * @return generated TO builder which represents <code>typedef</code>
350 * @throws NullPointerException
352 * <li>if <code>basePackageName</code> is null</li>
353 * <li>if <code>typedef</code> is null</li>
354 * <li>if QName of <code>typedef</code> is null</li>
357 @SuppressWarnings({ "rawtypes", "unchecked" })
358 public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
359 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode, final SchemaContext
360 schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
361 Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
362 Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
363 Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
365 final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
366 final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
367 final Module module = findParentModule(schemaContext, parentNode);
369 final GeneratedTOBuilderImpl unionGenTOBuilder;
370 unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName, true, false);
371 final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
372 unionGenTOBuilder.setDescription(typedefDescription);
373 unionGenTOBuilder.setReference(typedef.getReference());
374 unionGenTOBuilder.setSchemaPath((List) typedef.getPath().getPathFromRoot());
375 unionGenTOBuilder.setModuleName(module.getName());
377 generatedTOBuilders.add(unionGenTOBuilder);
378 unionGenTOBuilder.setIsUnion(true);
379 final List<String> regularExpressions = new ArrayList<>();
380 for (final TypeDefinition<?> unionType : unionTypes) {
381 final String unionTypeName = unionType.getQName().getLocalName();
382 if (unionType.getBaseType() != null) {
383 resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, regularExpressions,
384 parentNode, schemaContext, genTypeDefsContextMap);
385 } else if (unionType instanceof UnionTypeDefinition) {
386 generatedTOBuilders.add(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
387 unionGenTOBuilder.getFullyQualifiedName(), parentNode, schemaContext, genTypeDefsContextMap));
388 } else if (unionType instanceof EnumTypeDefinition) {
389 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
390 unionTypeName, unionGenTOBuilder);
391 updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
393 final Type javaType = javaTypeForSchemaDefType(unionType, parentNode, null, schemaContext,
394 genTypeDefsContextMap);
395 updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
398 if (!regularExpressions.isEmpty()) {
399 addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
402 //storeGenTO(typedef, unionGenTOBuilder, parentNode);
404 return generatedTOBuilders;
407 public Map<Module, Set<Type>> getAdditionalTypes() {
408 return this.additionalTypes;
411 public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) {
412 if (!Strings.isNullOrEmpty(units)) {
413 to.addConstant(Types.STRING, "Units", "\"" + units + "\"");
414 final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
415 prop.setReturnType(Types.STRING);
416 to.addToStringProperty(prop);
420 private Type javaTypeForSchemaDefType(final TypeDefinition<?> typeDefinition, final SchemaNode
421 parentNode, final Restrictions r, final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
422 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
423 final String typedefName = typeDefinition.getQName().getLocalName();
424 Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
426 // Deal with base types
427 if (typeDefinition.getBaseType() == null) {
428 // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type
429 // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates
430 // a base type which holds these constraints.
431 if (typeDefinition instanceof DecimalTypeDefinition) {
432 final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode, r);
438 // Deal with leafrefs/identityrefs
439 Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode, schemaContext, genTypeDefsContextMap);
444 ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode);
446 LOG.debug("Failed to resolve Java type for {}", typeDefinition);
452 Type returnType = javaTypeForExtendedType(typeDefinition, schemaContext, genTypeDefsContextMap);
453 if (r != null && !r.isEmpty() && returnType instanceof GeneratedTransferObject) {
454 final GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
455 final Module module = findParentModule(schemaContext, parentNode);
456 final Module module1 = findParentModule(schemaContext, typeDefinition);
457 final String basePackageName = BindingMapping.getRootPackageName(module);
458 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typeDefinition
459 .getPath(), BindingNamespaceType.Typedef);
460 final String genTOName =
461 JavaIdentifierNormalizer.normalizeSpecificIdentifier(typedefName, JavaIdentifier.CLASS);
462 final String name = packageName + "." + genTOName;
463 if (module.equals(module1) && !(returnType.getFullyQualifiedName().equals(name))) {
464 returnType = shadedTOWithRestrictions(gto, r);
472 * @param basePackageName
473 * string with name of package to which the module belongs
475 * string with the name of the module for to which the
476 * <code>typedef</code> belongs
478 * type definition of the node for which should be creted JAVA
479 * <code>Type</code> (usually generated TO)
480 * @return JAVA <code>Type</code> representation of <code>typedef</code> or
481 * <code>null</code> value if <code>basePackageName</code> or
482 * <code>modulName</code> or <code>typedef</code> or Q name of
483 * <code>typedef</code> equals <code>null</code>
485 private Type typedefToGeneratedType(final String basePackageName, final Module module, final
486 TypeDefinition<?> typedef, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, final Map<Module,
487 Set<Type>> additionalTypes, final SchemaContext schemaContext) {
488 final String moduleName = module.getName();
489 final Date moduleRevision = module.getRevision();
490 if ((basePackageName != null) && (moduleName != null) && (typedef != null)) {
491 final String typedefName = typedef.getQName().getLocalName();
492 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
493 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
494 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
496 if (innerTypeDefinition.getBaseType() != null) {
497 returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName,
498 module.getName(), schemaContext, genTypeDefsContextMap);
499 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
500 final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
501 (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef, schemaContext, genTypeDefsContextMap);
502 genTOBuilder.setTypedef(true);
503 genTOBuilder.setIsUnion(true);
504 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
505 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
506 returnType = genTOBuilder.toInstance();
507 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
508 // enums are automatically Serializable
509 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
510 // TODO units for typedef enum
511 returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef, schemaContext);
512 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
513 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
514 final GeneratedTOBuilder genTOBuilder =
515 provideGeneratedTOBuilderForBitsTypeDefinition(
516 basePackageName, bitsTypeDefinition, typedefName, module.getName());
517 genTOBuilder.setTypedef(true);
518 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
519 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
520 returnType = genTOBuilder.toInstance();
522 final Type javaType = javaTypeForSchemaDefType(innerTypeDefinition, typedef, null,
523 schemaContext, genTypeDefsContextMap);
524 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName());
526 if (returnType != null) {
527 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
528 Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
529 if (typeMap != null) {
530 if (typeMap.isEmpty()) {
531 typeMap = new HashMap<>(4);
532 modulesByDate.put(moduleRevision, typeMap);
534 typeMap.put(typedefName, returnType);
544 * Returns JAVA <code>Type</code> for instances of the type
545 * <code>ExtendedType</code>.
547 * @param typeDefinition
548 * type definition which is converted to JAVA <code>Type</code>
549 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
551 private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition, final SchemaContext
552 schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
554 final String typedefName = typeDefinition.getQName().getLocalName();
555 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
556 Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition, schemaContext, genTypeDefsContextMap);
557 if (returnType == null) {
558 final Module module = findParentModule(schemaContext, typeDefinition);
559 final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition);
560 if (module != null) {
561 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
562 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
563 if (genTOs != null) {
564 returnType = genTOs.get(typedefName);
566 if (returnType == null) {
567 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
568 baseTypeDef, typeDefinition, r);
576 * Returns JAVA <code>Type</code> for instances of the type
577 * <code>LeafrefTypeDefinition</code> or
578 * <code>IdentityrefTypeDefinition</code>.
580 * @param typeDefinition
581 * type definition which is converted to JAVA <code>Type</code>
582 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
584 private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
585 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
586 if (typeDefinition instanceof LeafrefTypeDefinition) {
587 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
588 if (isLeafRefSelfReference(leafref, parentNode, schemaContext)) {
589 throw new YangValidationException("Leafref " + leafref.toString() + " is referencing itself, incoming" +
590 " StackOverFlowError detected.");
592 return provideTypeForLeafref(leafref, parentNode, schemaContext, genTypeDefsContextMap);
593 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
594 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
595 return provideTypeForIdentityref(idref, schemaContext);
602 * Converts <code>leafrefType</code> to JAVA <code>Type</code>.
604 * The path of <code>leafrefType</code> is followed to find referenced node
605 * and its <code>Type</code> is returned.
608 * leafref type definition for which is the type sought
609 * @return JAVA <code>Type</code> of data schema node which is referenced in
610 * <code>leafrefType</code>
611 * @throws IllegalArgumentException
613 * <li>if <code>leafrefType</code> equal null</li>
614 * <li>if path statement of <code>leafrefType</code> equal null</li>
618 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode,
619 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
621 Type returnType = null;
622 Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
624 Preconditions.checkArgument(leafrefType.getPathStatement() != null,
625 "The Path Statement for Leafref Type Definition cannot be NULL!");
627 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
628 final String strXPath = xpath.toString();
630 if (strXPath != null) {
631 if (strXPath.indexOf('[') == -1) {
632 final Module module = findParentModule(schemaContext, parentNode);
633 Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
635 final SchemaNode dataNode;
636 if (xpath.isAbsolute()) {
637 dataNode = findDataSchemaNode(schemaContext, module, xpath);
639 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
641 Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)",
642 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
644 if (leafContainsEnumDefinition(dataNode)) {
645 returnType = this.referencedTypes.get(dataNode.getPath());
646 } else if (leafListContainsEnumDefinition(dataNode)) {
647 returnType = Types.listTypeFor(this.referencedTypes.get(dataNode.getPath()));
649 returnType = resolveTypeFromDataSchemaNode(dataNode, schemaContext, genTypeDefsContextMap);
652 returnType = Types.typeForClass(Object.class);
655 Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)",
656 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
661 * Checks if <code>dataNode</code> is <code>LeafSchemaNode</code> and if it
662 * so then checks if it is of type <code>EnumTypeDefinition</code>.
665 * data schema node for which is checked if it is leaf and if it
667 * @return boolean value
669 * <li>true - if <code>dataNode</code> is leaf of type enumeration</li>
670 * <li>false - other cases</li>
673 private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) {
674 if (dataNode instanceof LeafSchemaNode) {
675 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
676 //CompatUtils is not used here anymore
677 if (leaf.getType() instanceof EnumTypeDefinition) {
685 * Checks if <code>dataNode</code> is <code>LeafListSchemaNode</code> and if
686 * it so then checks if it is of type <code>EnumTypeDefinition</code>.
689 * data schema node for which is checked if it is leaflist and if
691 * @return boolean value
693 * <li>true - if <code>dataNode</code> is leaflist of type
695 * <li>false - other cases</li>
698 private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) {
699 if (dataNode instanceof LeafListSchemaNode) {
700 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
701 if (leafList.getType() instanceof EnumTypeDefinition) {
709 * Converts <code>dataNode</code> to JAVA <code>Type</code>.
712 * contains information about YANG type
713 * @return JAVA <code>Type</code> representation of <code>dataNode</code>
715 private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode, final SchemaContext schemaContext,
716 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
717 Type returnType = null;
718 if (dataNode != null) {
719 if (dataNode instanceof LeafSchemaNode) {
720 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
721 //not using CompatUtils here anymore
722 final TypeDefinition<?> type = leaf.getType();
723 returnType = javaTypeForSchemaDefType(type, leaf, null, schemaContext, genTypeDefsContextMap);
724 } else if (dataNode instanceof LeafListSchemaNode) {
725 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
726 returnType = javaTypeForSchemaDefType(leafList.getType(), leafList, null, schemaContext, genTypeDefsContextMap);
733 * Seeks for identity reference <code>idref</code> the JAVA
734 * <code>type</code>.<br />
738 * If identy which is referenced via <code>idref</code> has name <b>Idn</b>
739 * then returning type is <b>{@code Class<? extends Idn>}</b></i>
742 * identityref type definition for which JAVA <code>Type</code>
744 * @return JAVA <code>Type</code> of the identity which is refrenced through
747 private static Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref, final SchemaContext schemaContext) {
748 //TODO: incompatibility with Binding spec v2, get first or only one
749 final QName baseIdQName = idref.getIdentities().iterator().next().getQName();
750 final Module module = schemaContext.findModuleByNamespaceAndRevision(baseIdQName.getNamespace(),
751 baseIdQName.getRevision());
752 IdentitySchemaNode identity = null;
753 for (final IdentitySchemaNode id : module.getIdentities()) {
754 if (id.getQName().equals(baseIdQName)) {
758 Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists");
760 final String basePackageName = BindingMapping.getRootPackageName(module);
761 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath
762 (), BindingNamespaceType.Identity);
764 final String genTypeName = JavaIdentifierNormalizer.normalizeSpecificIdentifier(identity.getQName().getLocalName(),
765 JavaIdentifier.CLASS);
767 final Type baseType = Types.typeForClass(Class.class);
768 final Type paramType = Types.wildcardTypeFor(packageName, genTypeName, true, true);
769 return Types.parameterizedTypeFor(baseType, paramType);
773 * Converts <code>typedef</code> to the generated TO builder.
775 * @param basePackageName
776 * string with name of package to which the module belongs
778 * type definition from which is the generated TO builder created
779 * @return generated TO builder which contains data from
780 * <code>typedef</code> and <code>basePackageName</code>
782 @SuppressWarnings({ "rawtypes", "unchecked" })
783 private static GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef, final String moduleName) {
785 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typedef.getPath
786 (), BindingNamespaceType.Typedef);
787 final String typeDefTOName = typedef.getQName().getLocalName();
789 if ((packageName != null) && (typeDefTOName != null)) {
790 final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, typeDefTOName);
791 final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
793 newType.setDescription(typedefDescription);
794 newType.setReference(typedef.getReference());
795 newType.setSchemaPath((List) typedef.getPath().getPathFromRoot());
796 newType.setModuleName(moduleName);
803 private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto, final Restrictions r) {
804 final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName());
805 final GeneratedTransferObject parent = gto.getSuperType();
806 if (parent != null) {
807 gtob.setExtendsType(parent);
809 gtob.setRestrictions(r);
810 for (final GeneratedProperty gp : gto.getProperties()) {
811 final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName());
812 gpb.setValue(gp.getValue());
813 gpb.setReadOnly(gp.isReadOnly());
814 gpb.setAccessModifier(gp.getAccessModifier());
815 gpb.setReturnType(gp.getReturnType());
816 gpb.setFinal(gp.isFinal());
817 gpb.setStatic(gp.isStatic());
819 return gtob.toInstance();
823 * Adds a new property with the name <code>propertyName</code> and with type
824 * <code>type</code> to <code>unonGenTransObject</code>.
826 * @param unionGenTransObject
827 * generated TO to which should be property added
829 * JAVA <code>type</code> of the property which should be added
830 * to <code>unionGentransObject</code>
831 * @param propertyName
832 * string with name of property which should be added to
833 * <code>unionGentransObject</code>
835 private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) {
836 if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
837 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
838 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(propertyName, JavaIdentifier.METHOD));
839 propBuilder.setReturnType(type);
841 unionGenTransObject.addEqualsIdentity(propBuilder);
842 unionGenTransObject.addHashIdentity(propBuilder);
843 unionGenTransObject.addToStringProperty(propBuilder);
848 * Wraps code which handle case when union subtype is also of the type
849 * <code>UnionType</code>.
851 * In this case the new generated TO is created for union subtype (recursive
853 * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, UnionTypeDefinition,
854 * String, SchemaNode, SchemaContext, Map)}
855 * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
856 * <code>parentUnionGenTOBuilder</code> is created property which type is
857 * equal to new generated TO.
859 * @param parentUnionGenTOBuilder
860 * generated TO builder to which is the property with the child
861 * union subtype added
862 * @param basePackageName
863 * string with the name of the module package
864 * @param unionSubtype
865 * type definition which represents union subtype
866 * @return list of generated TO builders. The number of the builders can be
867 * bigger one due to recursive call of
868 * <code>provideGeneratedTOBuildersForUnionTypeDef</code> method.
870 private GeneratedTOBuilder resolveUnionSubtypeAsUnion(final GeneratedTOBuilder
871 parentUnionGenTOBuilder, final UnionTypeDefinition unionSubtype, final String basePackageName,
872 final SchemaNode parentNode, final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
874 final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
875 final GeneratedTOBuilder subUnionGenTOBUilder = provideGeneratedTOBuilderForUnionTypeDef(
876 basePackageName, unionSubtype, newTOBuilderName, parentNode, schemaContext, genTypeDefsContextMap);
878 final GeneratedPropertyBuilder propertyBuilder;
879 propertyBuilder = parentUnionGenTOBuilder
880 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
881 propertyBuilder.setReturnType(subUnionGenTOBUilder);
882 parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
883 parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
885 return subUnionGenTOBUilder;
889 * Converts output list of generated TO builders to one TO builder (first
890 * from list) which contains the remaining builders as its enclosing TO.
892 * @param basePackageName
893 * string with name of package to which the module belongs
895 * type definition which should be of type
896 * <code>UnionTypeDefinition</code>
898 * string with name for generated TO
899 * @return generated TO builder with the list of enclosed generated TO
902 public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
903 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode, final SchemaContext
904 schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
906 final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
907 typedef, typeDefName, parentNode, schemaContext, genTypeDefsContextMap);
908 Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef);
910 final GeneratedTOBuilder resultTOBuilder = builders.remove(0);
911 for (final GeneratedTOBuilder genTOBuilder : builders) {
912 resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
915 final GeneratedPropertyBuilder genPropBuilder;
917 genPropBuilder = resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY).setReadOnly(false);
918 resultTOBuilder.addEqualsIdentity(genPropBuilder);
919 resultTOBuilder.addHashIdentity(genPropBuilder);
920 resultTOBuilder.addToStringProperty(genPropBuilder);
922 provideGeneratedTOBuilderForUnionBuilder(findParentModule(schemaContext, parentNode), resultTOBuilder);
924 return resultTOBuilder;
928 private GeneratedTOBuilder provideGeneratedTOBuilderForUnionBuilder(final Module parentModule,
929 final GeneratedTOBuilder genTOBuilder) {
930 final String outerCls = Types.getOuterClassName(genTOBuilder);
931 final StringBuilder name;
932 if (outerCls != null) {
933 name = new StringBuilder(outerCls);
935 name = new StringBuilder();
937 name.append(genTOBuilder.getName());
938 name.append("Builder");
939 final GeneratedTOBuilderImpl unionBuilder = new GeneratedTOBuilderImpl(getOuterClassPackageName(genTOBuilder),
940 name.toString(), true);
941 unionBuilder.setIsUnionBuilder(true);
943 final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
944 method.setReturnType(genTOBuilder);
945 method.addParameter(Types.STRING, "defaultValue");
946 method.setAccessModifier(AccessModifier.PUBLIC);
947 method.setStatic(true);
949 final Set<Type> types = this.getAdditionalTypes().get(parentModule);
951 this.getAdditionalTypes().put(parentModule,
952 Sets.newHashSet(unionBuilder.toInstance()));
954 types.add(unionBuilder.toInstance());
961 * Wraps code which handle case when union subtype is of the type
962 * <code>ExtendedType</code>.
964 * If TO for this type already exists it is used for the creation of the
965 * property in <code>parentUnionGenTOBuilder</code>. In other case the base
966 * type is used for the property creation.
968 * @param parentUnionGenTOBuilder
969 * generated TO builder in which new property is created
970 * @param unionSubtype
971 * type definition of the <code>ExtendedType</code> type which
972 * represents union subtype
973 * @param regularExpressions
974 * list of strings with the regular expressions
976 * parent Schema Node for Extended Subtype
979 private static void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, final
980 TypeDefinition<?> unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode,
981 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
983 final String unionTypeName = unionSubtype.getQName().getLocalName();
984 final Type genTO = findGenTO(unionTypeName, unionSubtype, schemaContext, genTypeDefsContextMap);
986 updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, unionTypeName);
988 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
989 if (unionTypeName.equals(baseType.getQName().getLocalName())) {
990 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
992 if (javaType != null) {
993 updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
996 if (baseType instanceof StringTypeDefinition) {
997 regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype));
1003 * Returns string which contains the same value as <code>name</code> but
1004 * integer suffix is incremented by one. If <code>name</code> contains no
1005 * number suffix then number 1 is added.
1008 * string with name of augmented node
1009 * @return string with the number suffix incremented by one (or 1 is added)
1011 private static String provideAvailableNameForGenTOBuilder(final String name) {
1012 final Matcher mtch = NUMBERS_PATTERN.matcher(name);
1014 final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1;
1015 return name.substring(0, mtch.start()) + newSuffix;
1022 * Searches for generated TO for <code>searchedTypeDef</code> type
1023 * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap}
1025 * @param searchedTypeName
1026 * string with name of <code>searchedTypeDef</code>
1027 * @return generated TO for <code>searchedTypeDef</code> or
1028 * <code>null</code> it it doesn't exist
1030 private static Type findGenTO(final String searchedTypeName, final SchemaNode parentNode,
1031 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
1033 final Module typeModule = findParentModule(schemaContext, parentNode);
1034 if (typeModule != null && typeModule.getName() != null) {
1035 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(typeModule.getName());
1036 final Map<String, Type> genTOs = modulesByDate.get(typeModule.getRevision());
1037 if (genTOs != null) {
1038 return genTOs.get(searchedTypeName);
1045 * Adds enumeration to <code>typeBuilder</code>. The enumeration data are
1046 * taken from <code>enumTypeDef</code>.
1048 * @param enumTypeDef
1049 * enumeration type definition is source of enumeration data for
1050 * <code>typeBuilder</code>
1052 * string with the name of enumeration
1053 * @param typeBuilder
1054 * generated type builder to which is enumeration added
1055 * @return enumeration type which contains enumeration data form
1056 * <code>enumTypeDef</code>
1057 * @throws IllegalArgumentException
1059 * <li>if <code>enumTypeDef</code> equals null</li>
1060 * <li>if enum values of <code>enumTypeDef</code> equal null</li>
1061 * <li>if Q name of <code>enumTypeDef</code> equal null</li>
1062 * <li>if name of <code>enumTypeDef</code> equal null</li>
1063 * <li>if name of <code>typeBuilder</code> equal null</li>
1067 private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilderBase<?> typeBuilder) {
1068 Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
1069 Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
1070 "Local Name in EnumTypeDefinition QName cannot be NULL!");
1071 Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
1073 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumName);
1074 final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
1075 enumBuilder.setDescription(enumTypedefDescription);
1076 enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
1077 return enumBuilder.toInstance(enumBuilder);
1080 private static boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode,
1081 final SchemaContext schemaContext) {
1082 final SchemaNode leafRefValueNode;
1083 final RevisionAwareXPath leafRefXPath = leafref.getPathStatement();
1084 final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl(leafRefXPath.toString()
1085 .replaceAll("\\[(.*?)\\]", ""), leafRefXPath.isAbsolute());
1087 ///// skip leafrefs in augments - they're checked once augments are resolved
1088 final Iterator<QName> iterator = parentNode.getPath().getPathFromRoot().iterator();
1089 boolean isAugmenting = false;
1090 DataNodeContainer current = null;
1091 DataSchemaNode dataChildByName;
1093 while (iterator.hasNext() && !isAugmenting) {
1094 final QName next = iterator.next();
1095 if (current == null) {
1096 dataChildByName = schemaContext.getDataChildByName(next);
1098 dataChildByName = current.getDataChildByName(next);
1100 if (dataChildByName != null) {
1101 isAugmenting = dataChildByName.isAugmenting();
1105 if (dataChildByName instanceof DataNodeContainer) {
1106 current = (DataNodeContainer) dataChildByName;
1114 final Module parentModule = getParentModule(parentNode, schemaContext);
1115 if (!leafRefStrippedXPath.isAbsolute()) {
1116 leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
1117 parentNode, leafRefStrippedXPath);
1119 leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath);
1121 return (leafRefValueNode != null) && leafRefValueNode.equals(parentNode);