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.base.Optional;
30 import com.google.common.annotations.Beta;
31 import com.google.common.base.Preconditions;
32 import com.google.common.base.Strings;
33 import com.google.common.collect.Sets;
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.Date;
37 import java.util.HashMap;
38 import java.util.Iterator;
39 import java.util.List;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
45 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
46 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
47 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
48 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
49 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
50 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
51 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
52 import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
53 import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
54 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty;
55 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
56 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
57 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
58 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
59 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
60 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
61 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilderBase;
62 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
63 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
64 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
65 import org.opendaylight.yangtools.yang.common.QName;
66 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
67 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
68 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
69 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
70 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
71 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
72 import org.opendaylight.yangtools.yang.model.api.Module;
73 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
74 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
75 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
76 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
77 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
78 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
79 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
80 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
81 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
82 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
83 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
84 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
85 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
86 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
87 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
88 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
89 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
94 public final class TypeProviderImpl implements TypeProvider {
96 private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
97 private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
100 * Contains the schema data red from YANG files.
102 private final SchemaContext schemaContext;
105 * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
107 private final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
110 * Map which maps schema paths to JAVA <code>Type</code>.
112 private final Map<SchemaPath, Type> referencedTypes;
115 * Map for additional types e.g unions
117 private final Map<Module, Set<Type>> additionalTypes;
120 * Creates new instance of class <code>TypeProviderImpl</code>.
122 * @param schemaContext
123 * contains the schema data red from YANG files
124 * @throws IllegalArgumentException
125 * if <code>schemaContext</code> equal null.
127 public TypeProviderImpl(final SchemaContext schemaContext) {
128 this.schemaContext = schemaContext;
129 this.genTypeDefsContextMap = new HashMap<>();
130 this.referencedTypes = new HashMap<>();
131 this.additionalTypes = new HashMap<>();
132 resolveTypeDefsFromContext(schemaContext, this.genTypeDefsContextMap, this.additionalTypes);
136 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode,
137 ModuleContext context) {
138 return javaTypeForSchemaDefinitionType(type, parentNode, null, context);
142 * Converts schema definition type <code>typeDefinition</code> to JAVA
146 * type definition which is converted to JAVA type
147 * @throws IllegalArgumentException
149 * <li>if <code>typeDefinition</code> equal null</li>
150 * <li>if QName of <code>typeDefinition</code> equal null</li>
151 * <li>if name of <code>typeDefinition</code> equal null</li>
155 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode, final
156 Restrictions restrictions, ModuleContext context) {
157 return javaTypeForSchemaDefType(type, parentNode, restrictions, this.schemaContext, this
158 .genTypeDefsContextMap, context);
162 public String getTypeDefaultConstruction(final LeafSchemaNode node) {
167 public String getConstructorPropertyName(final SchemaNode node) {
172 public String getParamNameFromType(final TypeDefinition<?> type) {
176 public Map<String, Map<Date, Map<String, Type>>> getGenTypeDefsContextMap() {
177 return this.genTypeDefsContextMap;
181 * Passes through all modules and through all its type definitions and
182 * convert it to generated types.
184 * The modules are firstly sorted by mutual dependencies. The modules are
185 * sequentially passed. All type definitions of a module are at the
186 * beginning sorted so that type definition with less amount of references
187 * to other type definition are processed first.<br />
188 * For each module is created mapping record in the map
189 * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap}
190 * which map current module name to the map which maps type names to
191 * returned types (generated types).
194 private void resolveTypeDefsFromContext(final SchemaContext schemaContext, final Map<String, Map<Date, Map<String,
195 Type>>> genTypeDefsContextMap, final Map<Module, Set<Type>> additionalTypes) {
197 final Set<Module> modules = schemaContext.getModules();
198 Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
199 final List<Module> modulesSortedByDependency = ModuleDependencySort.sort(modules);
201 for (final Module module : modulesSortedByDependency) {
202 Map<Date, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
203 if (dateTypeMap == null) {
204 dateTypeMap = new HashMap<>();
206 dateTypeMap.put(module.getRevision(), Collections.emptyMap());
207 genTypeDefsContextMap.put(module.getName(), dateTypeMap);
210 modulesSortedByDependency.stream().filter(module -> module != null).forEach(module -> {
211 ModuleContext context = new ModuleContext();
212 final String basePackageName = packageNameWithNamespacePrefix(getRootPackageName(module),
213 BindingNamespaceType.Typedef);
214 final List<TypeDefinition<?>> typeDefinitions = getAllTypedefs(module);
215 final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
216 if (listTypeDefinitions != null) {
217 for (final TypeDefinition<?> typedef : listTypeDefinitions) {
218 typedefToGeneratedType(basePackageName, module, typedef, genTypeDefsContextMap,
219 additionalTypes, schemaContext, context);
226 * Converts <code>typeDefinition</code> to concrete JAVA <code>Type</code>.
228 * @param typeDefinition
229 * type definition which should be converted to JAVA
231 * @return JAVA <code>Type</code> which represents
232 * <code>typeDefinition</code>
233 * @throws IllegalArgumentException
235 * <li>if <code>typeDefinition</code> equal null</li>
236 * <li>if Q name of <code>typeDefinition</code></li>
237 * <li>if name of <code>typeDefinition</code></li>
240 public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
241 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
242 Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
243 "Type Definitions Local Name cannot be NULL!");
245 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
246 if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
247 final Module module = findParentModule(this.schemaContext, parentNode);
249 if (module != null) {
250 final Map<Date, Map<String, Type>> modulesByDate = this.genTypeDefsContextMap.get(module.getName());
251 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
252 if (genTOs != null) {
253 return genTOs.get(typeDefinition.getQName().getLocalName());
261 * Puts <code>refType</code> to map with key <code>refTypePath</code>
264 * schema path used as the map key
266 * type which represents the map value
267 * @throws IllegalArgumentException
269 * <li>if <code>refTypePath</code> equal null</li>
270 * <li>if <code>refType</code> equal null</li>
274 public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
275 Preconditions.checkArgument(refTypePath != null,
276 "Path reference of Enumeration Type Definition cannot be NULL!");
277 Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!");
278 this.referencedTypes.put(refTypePath, refType);
282 * Converts <code>typeDef</code> which should be of the type
283 * <code>BitsTypeDefinition</code> to <code>GeneratedTOBuilder</code>.
285 * All the bits of the typeDef are added to returning generated TO as
288 * @param basePackageName
289 * string with name of package to which the module belongs
291 * type definition from which is the generated TO builder created
293 * string with the name for generated TO builder
294 * @return generated TO builder which represents <code>typeDef</code>
295 * @throws IllegalArgumentException
297 * <li>if <code>typeDef</code> equals null</li>
298 * <li>if <code>basePackageName</code> equals null</li>
301 @SuppressWarnings({ "rawtypes", "unchecked" })
302 public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
303 final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName, ModuleContext context) {
305 Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
306 Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
308 if (typeDef instanceof BitsTypeDefinition) {
309 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
311 final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName,
312 true, false, context);
313 final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
315 genTOBuilder.setDescription(typedefDescription);
316 genTOBuilder.setReference(typeDef.getReference());
317 genTOBuilder.setSchemaPath((List) typeDef.getPath().getPathFromRoot());
318 genTOBuilder.setModuleName(moduleName);
319 genTOBuilder.setBaseType(typeDef);
321 final List<Bit> bitList = bitsTypeDefinition.getBits();
322 GeneratedPropertyBuilder genPropertyBuilder;
323 for (final Bit bit : bitList) {
324 final String name = bit.getName();
326 genTOBuilder.addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
327 genPropertyBuilder.setReadOnly(true);
328 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
330 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
331 genTOBuilder.addHashIdentity(genPropertyBuilder);
332 genTOBuilder.addToStringProperty(genPropertyBuilder);
341 * Converts <code>typedef</code> to generated TO with
342 * <code>typeDefName</code>. Every union type from <code>typedef</code> is
343 * added to generated TO builder as property.
345 * @param basePackageName
346 * string with name of package to which the module belongs
348 * type definition which should be of type
349 * <code>UnionTypeDefinition</code>
351 * string with name for generated TO
352 * @return generated TO builder which represents <code>typedef</code>
353 * @throws NullPointerException
355 * <li>if <code>basePackageName</code> is null</li>
356 * <li>if <code>typedef</code> is null</li>
357 * <li>if QName of <code>typedef</code> is null</li>
360 @SuppressWarnings({ "rawtypes", "unchecked" })
361 public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
362 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
363 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
364 Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
365 Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
366 Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
368 final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
369 final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
370 final Module module = findParentModule(schemaContext, parentNode);
372 final GeneratedTOBuilderImpl unionGenTOBuilder;
373 unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName, true, false,
375 final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
376 unionGenTOBuilder.setDescription(typedefDescription);
377 unionGenTOBuilder.setReference(typedef.getReference());
378 unionGenTOBuilder.setSchemaPath((List) typedef.getPath().getPathFromRoot());
379 unionGenTOBuilder.setModuleName(module.getName());
381 generatedTOBuilders.add(unionGenTOBuilder);
382 unionGenTOBuilder.setIsUnion(true);
383 final List<String> regularExpressions = new ArrayList<>();
384 for (final TypeDefinition<?> unionType : unionTypes) {
385 final String unionTypeName = unionType.getQName().getLocalName();
386 if (unionType.getBaseType() != null) {
387 resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, regularExpressions,
388 parentNode, schemaContext, genTypeDefsContextMap);
389 } else if (unionType instanceof UnionTypeDefinition) {
390 generatedTOBuilders.add(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
391 unionGenTOBuilder.getFullyQualifiedName(), parentNode, schemaContext, genTypeDefsContextMap,
393 } else if (unionType instanceof EnumTypeDefinition) {
394 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
395 unionTypeName, unionGenTOBuilder, context);
396 updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
398 final Type javaType = javaTypeForSchemaDefType(unionType, parentNode, null, schemaContext,
399 genTypeDefsContextMap, context);
400 updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
403 if (!regularExpressions.isEmpty()) {
404 addStringRegExAsConstant(unionGenTOBuilder, regularExpressions);
407 //storeGenTO(typedef, unionGenTOBuilder, parentNode);
409 return generatedTOBuilders;
412 public Map<Module, Set<Type>> getAdditionalTypes() {
413 return this.additionalTypes;
416 public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) {
417 if (!Strings.isNullOrEmpty(units)) {
418 to.addConstant(Types.STRING, "Units", "\"" + units + "\"");
419 final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
420 prop.setReturnType(Types.STRING);
421 to.addToStringProperty(prop);
425 private Type javaTypeForSchemaDefType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
426 final Restrictions r, final SchemaContext schemaContext,
427 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
428 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
429 final String typedefName = typeDefinition.getQName().getLocalName();
430 Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
432 // Deal with base types
433 if (typeDefinition.getBaseType() == null) {
434 // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type
435 // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates
436 // a base type which holds these constraints.
437 if (typeDefinition instanceof DecimalTypeDefinition) {
438 final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType
439 (typeDefinition, parentNode, r, null);
445 // Deal with leafrefs/identityrefs
446 Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode, schemaContext,
447 genTypeDefsContextMap, context);
452 ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode,
455 LOG.debug("Failed to resolve Java type for {}", typeDefinition);
461 Type returnType = javaTypeForExtendedType(typeDefinition, schemaContext, genTypeDefsContextMap, context);
462 if (r != null && !r.isEmpty() && returnType instanceof GeneratedTransferObject) {
463 final GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
464 final Module module = findParentModule(schemaContext, parentNode);
465 final Module module1 = findParentModule(schemaContext, typeDefinition);
466 final String basePackageName = BindingMapping.getRootPackageName(module);
467 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typeDefinition
468 .getPath(), BindingNamespaceType.Typedef);
469 final String genTOName =
470 JavaIdentifierNormalizer.normalizeSpecificIdentifier(typedefName, JavaIdentifier.CLASS);
471 final String name = packageName + "." + genTOName;
472 if (module.equals(module1) && !(returnType.getFullyQualifiedName().equals(name))) {
473 returnType = shadedTOWithRestrictions(gto, r, context);
481 * @param basePackageName
482 * string with name of package to which the module belongs
484 * string with the name of the module for to which the
485 * <code>typedef</code> belongs
487 * type definition of the node for which should be creted JAVA
488 * <code>Type</code> (usually generated TO)
489 * @return JAVA <code>Type</code> representation of <code>typedef</code> or
490 * <code>null</code> value if <code>basePackageName</code> or
491 * <code>modulName</code> or <code>typedef</code> or Q name of
492 * <code>typedef</code> equals <code>null</code>
494 private Type typedefToGeneratedType(final String basePackageName, final Module module,
495 final TypeDefinition<?> typedef, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
496 final Map<Module, Set<Type>> additionalTypes, final SchemaContext schemaContext, ModuleContext context) {
497 final String moduleName = module.getName();
498 final Date moduleRevision = module.getRevision();
499 if ((basePackageName != null) && (moduleName != null) && (typedef != null)) {
500 final String typedefName = typedef.getQName().getLocalName();
501 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
502 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
503 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
505 if (innerTypeDefinition.getBaseType() != null) {
506 returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName,
507 module.getName(), schemaContext, genTypeDefsContextMap, context);
508 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
509 final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
510 (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef, schemaContext,
511 genTypeDefsContextMap, context);
512 genTOBuilder.setTypedef(true);
513 genTOBuilder.setIsUnion(true);
514 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
515 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
516 returnType = genTOBuilder.toInstance();
517 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
518 // enums are automatically Serializable
519 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
520 // TODO units for typedef enum
521 returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef, schemaContext, context);
522 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
523 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
524 final GeneratedTOBuilder genTOBuilder =
525 provideGeneratedTOBuilderForBitsTypeDefinition(
526 basePackageName, bitsTypeDefinition, typedefName, module.getName(), context);
527 genTOBuilder.setTypedef(true);
528 addUnitsToGenTO(genTOBuilder, typedef.getUnits());
529 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
530 returnType = genTOBuilder.toInstance();
532 final Type javaType = javaTypeForSchemaDefType(innerTypeDefinition, typedef, null,
533 schemaContext, genTypeDefsContextMap, context);
534 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName(), context);
536 if (returnType != null) {
537 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
538 Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
539 if (typeMap != null) {
540 if (typeMap.isEmpty()) {
541 typeMap = new HashMap<>(4);
542 modulesByDate.put(moduleRevision, typeMap);
544 typeMap.put(typedefName, returnType);
554 * Returns JAVA <code>Type</code> for instances of the type
555 * <code>ExtendedType</code>.
557 * @param typeDefinition
558 * type definition which is converted to JAVA <code>Type</code>
559 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
561 private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition, final SchemaContext schemaContext,
562 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
564 final String typedefName = typeDefinition.getQName().getLocalName();
565 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
566 Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition, schemaContext,
567 genTypeDefsContextMap, context);
568 if (returnType == null) {
569 final Module module = findParentModule(schemaContext, typeDefinition);
570 final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition);
571 if (module != null) {
572 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
573 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
574 if (genTOs != null) {
575 returnType = genTOs.get(typedefName);
577 if (returnType == null) {
578 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
579 baseTypeDef, typeDefinition, r, null);
587 * Returns JAVA <code>Type</code> for instances of the type
588 * <code>LeafrefTypeDefinition</code> or
589 * <code>IdentityrefTypeDefinition</code>.
591 * @param typeDefinition
592 * type definition which is converted to JAVA <code>Type</code>
593 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
595 private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
596 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
597 ModuleContext context) {
598 if (typeDefinition instanceof LeafrefTypeDefinition) {
599 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
600 if (isLeafRefSelfReference(leafref, parentNode, schemaContext)) {
601 throw new YangValidationException("Leafref " + leafref.toString() + " is referencing itself, incoming" +
602 " StackOverFlowError detected.");
604 return provideTypeForLeafref(leafref, parentNode, schemaContext, genTypeDefsContextMap, context);
605 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
606 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
607 return provideTypeForIdentityref(idref, schemaContext);
614 * Converts <code>leafrefType</code> to JAVA <code>Type</code>.
616 * The path of <code>leafrefType</code> is followed to find referenced node
617 * and its <code>Type</code> is returned.
620 * leafref type definition for which is the type sought
621 * @return JAVA <code>Type</code> of data schema node which is referenced in
622 * <code>leafrefType</code>
623 * @throws IllegalArgumentException
625 * <li>if <code>leafrefType</code> equal null</li>
626 * <li>if path statement of <code>leafrefType</code> equal null</li>
630 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode,
631 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
632 ModuleContext context) {
634 Type returnType = null;
635 Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
637 Preconditions.checkArgument(leafrefType.getPathStatement() != null,
638 "The Path Statement for Leafref Type Definition cannot be NULL!");
640 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
641 final String strXPath = xpath.toString();
642 if (strXPath != null) {
643 if (strXPath.indexOf('[') == -1) {
645 if ((parentNode instanceof DerivableSchemaNode) && ((DerivableSchemaNode) parentNode).isAddedByUses()) {
646 final Optional<? extends SchemaNode> originalNode = ((DerivableSchemaNode) parentNode).getOriginal();
647 Preconditions.checkArgument(originalNode.isPresent(), "originalNode can not be null.");
648 module = findParentModule(schemaContext, originalNode.get());
650 module = findParentModule(schemaContext, parentNode);
652 Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
654 final SchemaNode dataNode;
655 if (xpath.isAbsolute()) {
656 dataNode = findDataSchemaNode(schemaContext, module, xpath);
658 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
660 Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)",
661 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
663 if (leafContainsEnumDefinition(dataNode)) {
664 returnType = this.referencedTypes.get(dataNode.getPath());
665 } else if (leafListContainsEnumDefinition(dataNode)) {
666 returnType = Types.listTypeFor(this.referencedTypes.get(dataNode.getPath()));
668 returnType = resolveTypeFromDataSchemaNode(dataNode, schemaContext, genTypeDefsContextMap, context);
671 returnType = Types.typeForClass(Object.class);
674 Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)",
675 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
680 * Checks if <code>dataNode</code> is <code>LeafSchemaNode</code> and if it
681 * so then checks if it is of type <code>EnumTypeDefinition</code>.
684 * data schema node for which is checked if it is leaf and if it
686 * @return boolean value
688 * <li>true - if <code>dataNode</code> is leaf of type enumeration</li>
689 * <li>false - other cases</li>
692 private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) {
693 if (dataNode instanceof LeafSchemaNode) {
694 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
695 //CompatUtils is not used here anymore
696 if (leaf.getType() instanceof EnumTypeDefinition) {
704 * Checks if <code>dataNode</code> is <code>LeafListSchemaNode</code> and if
705 * it so then checks if it is of type <code>EnumTypeDefinition</code>.
708 * data schema node for which is checked if it is leaflist and if
710 * @return boolean value
712 * <li>true - if <code>dataNode</code> is leaflist of type
714 * <li>false - other cases</li>
717 private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) {
718 if (dataNode instanceof LeafListSchemaNode) {
719 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
720 if (leafList.getType() instanceof EnumTypeDefinition) {
728 * Converts <code>dataNode</code> to JAVA <code>Type</code>.
731 * contains information about YANG type
732 * @return JAVA <code>Type</code> representation of <code>dataNode</code>
734 private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode, final SchemaContext schemaContext,
735 final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap, ModuleContext context) {
736 Type returnType = null;
737 if (dataNode != null) {
738 if (dataNode instanceof LeafSchemaNode) {
739 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
740 //not using CompatUtils here anymore
741 final TypeDefinition<?> type = leaf.getType();
742 returnType = javaTypeForSchemaDefType(type, leaf, null, schemaContext, genTypeDefsContextMap, context);
743 } else if (dataNode instanceof LeafListSchemaNode) {
744 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
745 returnType = javaTypeForSchemaDefType(leafList.getType(), leafList, null, schemaContext,
746 genTypeDefsContextMap, context);
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.Identity);
784 final String genTypeName = JavaIdentifierNormalizer.normalizeSpecificIdentifier(identity.getQName().getLocalName(),
785 JavaIdentifier.CLASS);
787 final Type baseType = Types.typeForClass(Class.class);
788 final Type paramType = Types.wildcardTypeFor(packageName, genTypeName, true, true, null);
789 return Types.parameterizedTypeFor(baseType, paramType);
792 private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto,
793 final Restrictions r, ModuleContext context) {
794 final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName(), context);
795 final GeneratedTransferObject parent = gto.getSuperType();
796 if (parent != null) {
797 gtob.setExtendsType(parent);
799 gtob.setRestrictions(r);
800 for (final GeneratedProperty gp : gto.getProperties()) {
801 final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName());
802 gpb.setValue(gp.getValue());
803 gpb.setReadOnly(gp.isReadOnly());
804 gpb.setAccessModifier(gp.getAccessModifier());
805 gpb.setReturnType(gp.getReturnType());
806 gpb.setFinal(gp.isFinal());
807 gpb.setStatic(gp.isStatic());
809 return gtob.toInstance();
813 * Adds a new property with the name <code>propertyName</code> and with type
814 * <code>type</code> to <code>unonGenTransObject</code>.
816 * @param unionGenTransObject
817 * generated TO to which should be property added
819 * JAVA <code>type</code> of the property which should be added
820 * to <code>unionGentransObject</code>
821 * @param propertyName
822 * string with name of property which should be added to
823 * <code>unionGentransObject</code>
825 private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) {
826 if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
827 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
828 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(propertyName, JavaIdentifier.METHOD));
829 propBuilder.setReturnType(type);
831 unionGenTransObject.addEqualsIdentity(propBuilder);
832 unionGenTransObject.addHashIdentity(propBuilder);
833 unionGenTransObject.addToStringProperty(propBuilder);
838 * Wraps code which handle case when union subtype is also of the type
839 * <code>UnionType</code>.
841 * In this case the new generated TO is created for union subtype (recursive
843 * {@link #provideGeneratedTOBuilderForUnionTypeDef(String, UnionTypeDefinition, String, SchemaNode, SchemaContext, Map, ModuleContext)}
844 * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
845 * <code>parentUnionGenTOBuilder</code> is created property which type is
846 * equal to new generated TO.
848 * @param parentUnionGenTOBuilder
849 * generated TO builder to which is the property with the child
850 * union subtype added
851 * @param basePackageName
852 * string with the name of the module package
853 * @param unionSubtype
854 * type definition which represents union subtype
855 * @return list of generated TO builders. The number of the builders can be
856 * bigger one due to recursive call of
857 * <code>provideGeneratedTOBuildersForUnionTypeDef</code> method.
859 private GeneratedTOBuilder resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
860 final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode,
861 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
862 ModuleContext context) {
864 final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
865 final GeneratedTOBuilder subUnionGenTOBUilder = provideGeneratedTOBuilderForUnionTypeDef(
866 basePackageName, unionSubtype, newTOBuilderName, parentNode, schemaContext, genTypeDefsContextMap,
869 final GeneratedPropertyBuilder propertyBuilder;
870 propertyBuilder = parentUnionGenTOBuilder
871 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
872 propertyBuilder.setReturnType(subUnionGenTOBUilder);
873 parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
874 parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
876 return subUnionGenTOBUilder;
880 * Converts output list of generated TO builders to one TO builder (first
881 * from list) which contains the remaining builders as its enclosing TO.
883 * @param basePackageName
884 * string with name of package to which the module belongs
886 * type definition which should be of type
887 * <code>UnionTypeDefinition</code>
889 * string with name for generated TO
890 * @return generated TO builder with the list of enclosed generated TO
893 public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
894 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
895 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap,
896 ModuleContext context) {
898 final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
899 typedef, typeDefName, parentNode, schemaContext, genTypeDefsContextMap, context);
900 Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef);
902 final GeneratedTOBuilder resultTOBuilder = builders.remove(0);
903 for (final GeneratedTOBuilder genTOBuilder : builders) {
904 resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
907 final GeneratedPropertyBuilder genPropBuilder;
909 genPropBuilder = resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY).setReadOnly(false);
910 resultTOBuilder.addEqualsIdentity(genPropBuilder);
911 resultTOBuilder.addHashIdentity(genPropBuilder);
912 resultTOBuilder.addToStringProperty(genPropBuilder);
914 provideGeneratedTOBuilderForUnionBuilder(findParentModule(schemaContext, parentNode), resultTOBuilder);
916 return resultTOBuilder;
920 private GeneratedTOBuilder provideGeneratedTOBuilderForUnionBuilder(final Module parentModule,
921 final GeneratedTOBuilder genTOBuilder) {
922 final String outerCls = Types.getOuterClassName(genTOBuilder);
923 final StringBuilder name;
924 if (outerCls != null) {
925 name = new StringBuilder(outerCls);
927 name = new StringBuilder();
929 name.append(genTOBuilder.getName());
930 name.append("Builder");
931 final GeneratedTOBuilderImpl unionBuilder = new GeneratedTOBuilderImpl(getOuterClassPackageName(genTOBuilder),
932 name.toString(), true);
933 unionBuilder.setIsUnionBuilder(true);
935 final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
936 method.setReturnType(genTOBuilder);
937 method.addParameter(Types.STRING, "defaultValue");
938 method.setAccessModifier(AccessModifier.PUBLIC);
939 method.setStatic(true);
941 final Set<Type> types = this.getAdditionalTypes().get(parentModule);
943 this.getAdditionalTypes().put(parentModule,
944 Sets.newHashSet(unionBuilder.toInstance()));
946 types.add(unionBuilder.toInstance());
953 * Wraps code which handle case when union subtype is of the type
954 * <code>ExtendedType</code>.
956 * If TO for this type already exists it is used for the creation of the
957 * property in <code>parentUnionGenTOBuilder</code>. In other case the base
958 * type is used for the property creation.
960 * @param parentUnionGenTOBuilder
961 * generated TO builder in which new property is created
962 * @param unionSubtype
963 * type definition of the <code>ExtendedType</code> type which
964 * represents union subtype
965 * @param regularExpressions
966 * list of strings with the regular expressions
968 * parent Schema Node for Extended Subtype
971 private static void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
972 final TypeDefinition<?> unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode,
973 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
975 final String unionTypeName = unionSubtype.getQName().getLocalName();
976 final Type genTO = findGenTO(unionTypeName, unionSubtype, schemaContext, genTypeDefsContextMap);
978 updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, unionTypeName);
980 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
981 if (unionTypeName.equals(baseType.getQName().getLocalName())) {
982 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
984 if (javaType != null) {
985 updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
988 if (baseType instanceof StringTypeDefinition) {
989 regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype));
995 * Returns string which contains the same value as <code>name</code> but
996 * integer suffix is incremented by one. If <code>name</code> contains no
997 * number suffix then number 1 is added.
1000 * string with name of augmented node
1001 * @return string with the number suffix incremented by one (or 1 is added)
1003 private static String provideAvailableNameForGenTOBuilder(final String name) {
1004 final Matcher mtch = NUMBERS_PATTERN.matcher(name);
1006 final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1;
1007 return name.substring(0, mtch.start()) + newSuffix;
1014 * Searches for generated TO for <code>searchedTypeDef</code> type
1015 * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap}
1017 * @param searchedTypeName
1018 * string with name of <code>searchedTypeDef</code>
1019 * @return generated TO for <code>searchedTypeDef</code> or
1020 * <code>null</code> it it doesn't exist
1022 private static Type findGenTO(final String searchedTypeName, final SchemaNode parentNode,
1023 final SchemaContext schemaContext, final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap) {
1025 final Module typeModule = findParentModule(schemaContext, parentNode);
1026 if (typeModule != null && typeModule.getName() != null) {
1027 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(typeModule.getName());
1028 final Map<String, Type> genTOs = modulesByDate.get(typeModule.getRevision());
1029 if (genTOs != null) {
1030 return genTOs.get(searchedTypeName);
1037 * Adds enumeration to <code>typeBuilder</code>. The enumeration data are
1038 * taken from <code>enumTypeDef</code>.
1040 * @param enumTypeDef
1041 * enumeration type definition is source of enumeration data for
1042 * <code>typeBuilder</code>
1044 * string with the name of enumeration
1045 * @param typeBuilder
1046 * generated type builder to which is enumeration added
1047 * @return enumeration type which contains enumeration data form
1048 * <code>enumTypeDef</code>
1049 * @throws IllegalArgumentException
1051 * <li>if <code>enumTypeDef</code> equals null</li>
1052 * <li>if enum values of <code>enumTypeDef</code> equal null</li>
1053 * <li>if Q name of <code>enumTypeDef</code> equal null</li>
1054 * <li>if name of <code>enumTypeDef</code> equal null</li>
1055 * <li>if name of <code>typeBuilder</code> equal null</li>
1059 private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef,
1060 final String enumName, final GeneratedTypeBuilderBase<?> typeBuilder, ModuleContext context) {
1061 Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
1062 Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
1063 "Local Name in EnumTypeDefinition QName cannot be NULL!");
1064 Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
1066 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumName, context);
1067 final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
1068 enumBuilder.setDescription(enumTypedefDescription);
1069 enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
1070 return enumBuilder.toInstance(enumBuilder);
1073 private static boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode,
1074 final SchemaContext schemaContext) {
1075 final SchemaNode leafRefValueNode;
1076 final RevisionAwareXPath leafRefXPath = leafref.getPathStatement();
1077 final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl(leafRefXPath.toString()
1078 .replaceAll("\\[(.*?)\\]", ""), leafRefXPath.isAbsolute());
1080 ///// skip leafrefs in augments - they're checked once augments are resolved
1081 final Iterator<QName> iterator = parentNode.getPath().getPathFromRoot().iterator();
1082 boolean isAugmenting = false;
1083 DataNodeContainer current = null;
1084 DataSchemaNode dataChildByName;
1086 while (iterator.hasNext() && !isAugmenting) {
1087 final QName next = iterator.next();
1088 if (current == null) {
1089 dataChildByName = schemaContext.getDataChildByName(next);
1091 dataChildByName = current.getDataChildByName(next);
1093 if (dataChildByName != null) {
1094 isAugmenting = dataChildByName.isAugmenting();
1098 if (dataChildByName instanceof DataNodeContainer) {
1099 current = (DataNodeContainer) dataChildByName;
1107 final Module parentModule = getParentModule(parentNode, schemaContext);
1108 if (!leafRefStrippedXPath.isAbsolute()) {
1109 leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
1110 parentNode, leafRefStrippedXPath);
1112 leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath);
1114 return (leafRefValueNode != null) && leafRefValueNode.equals(parentNode);