Bug appears when two augments point to same target node which was added by uses statement.
Change-Id: I92a9d0586c9c94cd92a929a492272cdbd54be492
Signed-off-by: Martin Vitez <mvitez@cisco.com>
import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;\r
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;\r
import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort\r
-import org.opendaylight.yangtools.yang.model.util.ExtendedType;\r
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;\rimport org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.model.api.UsesNode
+import java.util.HashSet
+
public class BindingGeneratorImpl implements BindingGenerator {\r
/**\r
* Outter key represents the package name. Outter value represents map of\r
val basePackageName = moduleNamespaceToPackageName(module);\r
val List<AugmentationSchema> augmentations = resolveAugmentations(module);\r
for (augment : augmentations) {\r
- generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment));\r
+ generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment, module));\r
}\r
return generatedTypes;\r
}\r
val moduleName = parseToClassName(module.name) + postfix;\r
\r
return new GeneratedTypeBuilderImpl(packageName, moduleName);\r
-\r
}\r
\r
/**\r
* <li>if target path of <code>augSchema</code> equals null</li>\r
* </ul>\r
*/\r
- private def List<Type> augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema) {\r
+ private def List<Type> augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module) {\r
checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");\r
checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");\r
checkState(augSchema.targetPath !== null,\r
// EVERY augmented interface will extends Augmentation<T> interface\r
// and DataObject interface!!!\r
val targetPath = augSchema.targetPath;\r
- val targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);\r
+ var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);\r
+ if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) {\r
+ targetSchemaNode = findOriginalTargetFromGrouping(targetPath, module, targetSchemaNode as DataSchemaNode);\r
+ }\r
+\r
if(targetSchemaNode !== null) {\r
var targetType = yangToJavaMapping.get(targetSchemaNode.path);\r
if(targetType == null) {\r
return genTypes;\r
}\r
\r
+ private def DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, Module module, DataSchemaNode targetSchemaNode) {\r
+ val path = new ArrayList<QName>(targetPath.getPath());\r
+ path.remove(path.size()-1);\r
+ var DataNodeContainer parent = null;\r
+\r
+ if (path.isEmpty()) {\r
+ parent = module;\r
+ } else {\r
+ parent = findNodeInSchemaContext(schemaContext, path) as DataNodeContainer;\r
+ }\r
+\r
+ val Set<UsesNode> usesNodes = parent.getUses();\r
+ if (usesNodes == null || usesNodes.isEmpty()) {\r
+ return targetSchemaNode;\r
+ }\r
+ val Set<SchemaPath> groupingPaths = new HashSet<SchemaPath>();\r
+ for (uses : usesNodes) {\r
+ groupingPaths.add(uses.getGroupingPath());\r
+ }\r
+ val Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();\r
+ for (gp : groupingPaths) {\r
+ groupings.add(findGrouping(schemaContext, module, gp.getPath()));\r
+ }\r
+\r
+ var DataSchemaNode result = findNodeInGroupings(groupings, targetSchemaNode.getQName().localName);\r
+ return result;\r
+ }\r
+\r
+ private def DataSchemaNode findNodeInGroupings(Set<GroupingDefinition> groupings, String name) {\r
+ for (gr : groupings) {\r
+ var DataSchemaNode node = gr.getDataChildByName(name);\r
+ if (node != null) {\r
+ return node;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
/**\r
* Returns a generated type builder for an augmentation.\r
*\r
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
import java.util.Date
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition
+import java.util.Set
/**
* The Schema Context Util contains support methods for searching through Schema Context modules for specified schema
}
- private static def SchemaNode findNodeInSchemaContext(SchemaContext context, List<QName> path) {
+ public static def SchemaNode findNodeInSchemaContext(SchemaContext context, List<QName> path) {
val current = path.get(0);
val module = context.findModuleByNamespaceAndRevision(current.namespace,current.revision);
if(module === null) return null;
return findNodeInModule(module,path);
}
-
+
+ public static def GroupingDefinition findGrouping(SchemaContext context, Module module, List<QName> path) {
+ var first = path.get(0);
+ var firstPrefix = first.getPrefix();
+ var Module m = context.findModuleByNamespace(first.namespace).iterator().next();
+ var DataNodeContainer currentParent = m;
+ for (qname : path) {
+ var boolean found = false;
+ var DataNodeContainer node = currentParent.getDataChildByName(qname.localName) as DataNodeContainer;
+ if (node == null) {
+ var Set<GroupingDefinition> groupings = currentParent.getGroupings();
+ for (gr : groupings) {
+ if(gr.getQName().localName.equals(qname.localName)) {
+ currentParent = gr;
+ found = true;
+ }
+ }
+ } else {
+ found = true;
+ currentParent = node;
+ }
+ if (!found) {
+ throw new IllegalArgumentException("Failed to find referenced grouping: " + path + "(" + qname.localName + ")");
+ }
+ }
+
+ return currentParent as GroupingDefinition;
+ }
+
private static def SchemaNode findNodeInModule(Module module, List<QName> path) {
val current = path.get(0);
var SchemaNode node = module.getDataChildByName(current);
private boolean addedByUses;
private boolean augmenting;
private AugmentationSchemaBuilder parentAugment;
- private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();
- private final List<SchemaNodeBuilder> refineBuilders = new ArrayList<SchemaNodeBuilder>();
- private final List<RefineHolder> refines = new ArrayList<RefineHolder>();
+ private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<>();
+ private final List<SchemaNodeBuilder> refineBuilders = new ArrayList<>();
+ private final List<RefineHolder> refines = new ArrayList<>();
+ /**
+ * Copies of target grouping child nodes.
+ */
private final Set<DataSchemaNodeBuilder> targetChildren = new HashSet<>();
+
+ /**
+ * Copies of target grouping groupings.
+ */
private final Set<GroupingBuilder> targetGroupings = new HashSet<>();
+
+ /**
+ * Copies of target grouping typedefs.
+ */
private final Set<TypeDefinitionBuilder> targetTypedefs = new HashSet<>();
+
+ /**
+ * Copies of target grouping unknown nodes.
+ */
private final List<UnknownSchemaNodeBuilder> targetUnknownNodes = new ArrayList<>();
private final boolean isCopy;
instance.setAddedByUses(addedByUses);
// AUGMENTATIONS
- final Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();
+ final Set<AugmentationSchema> augments = new HashSet<>();
for (AugmentationSchemaBuilder builder : addedAugments) {
augments.add(builder.build());
}
instance.setAugmentations(augments);
// REFINES
- final Map<SchemaPath, SchemaNode> refineNodes = new HashMap<SchemaPath, SchemaNode>();
+ final Map<SchemaPath, SchemaNode> refineNodes = new HashMap<>();
for (SchemaNodeBuilder refineBuilder : refineBuilders) {
SchemaNode refineNode = refineBuilder.build();
refineNodes.put(refineNode.getPath(), refineNode);
instance.setRefines(refineNodes);
// UNKNOWN NODES
- List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+ List<UnknownSchemaNode> unknownNodes = new ArrayList<>();
for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
unknownNodes.add(b.build());
}
private static def searchUses(DataNodeContainerBuilder dataNodeContainerParent, String name) {
var currentName = name;
for (unb : dataNodeContainerParent.usesNodes) {
- val result = findNodeInUses(currentName, unb);
+ var result = searchInUsesTarget(currentName, unb);
+ if (result != null) {
+ return result;
+ }
+
+ result = findNodeInUses(currentName, unb);
if (result != null) {
var copy = CopyUtils.copy(result, unb.getParent(), true);
unb.getTargetChildren().add(copy);
return true;
}
+ private static def DataSchemaNodeBuilder searchInUsesTarget(String localName, UsesNodeBuilder uses) {
+ for(child : uses.targetChildren) {
+ if (child.getQName().getLocalName().equals(localName)) {
+ return child;
+ }
+ }
+ }
+
/**
* Find node with given name in uses target.
*
* @return node with given name if found, null otherwise
*/
private static def DataSchemaNodeBuilder findNodeInUses(String localName, UsesNodeBuilder uses) {
- for(child : uses.targetChildren) {
- if (child.getQName().getLocalName().equals(localName)) {
- return child;
- }
- }
-
val target = uses.groupingBuilder;
for (child : target.childNodeBuilders) {
if (child.getQName().getLocalName().equals(localName)) {