/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Bell Canada. All rights reserved.
+ * Modifications Copyright (C) 2021 Pantheon.tech
+ * Modifications Copyright (C) 2022 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.utils.YangUtils;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
@Slf4j
public class DataNodeBuilder {
- private NormalizedNode<?, ?> normalizedNodeTree;
+ private NormalizedNode normalizedNodeTree;
private String xpath;
+ private String moduleNamePrefix;
+ private String parentNodeXpath = "";
+ private Map<String, Serializable> leaves = Collections.emptyMap();
private Collection<DataNode> childDataNodes = Collections.emptySet();
+ /**
+ * To use parent node xpath for creating {@link DataNode}.
+ *
+ * @param parentNodeXpath xpath of a parent node
+ * @return this {@link DataNodeBuilder} object
+ */
+ public DataNodeBuilder withParentNodeXpath(final String parentNodeXpath) {
+ this.parentNodeXpath = parentNodeXpath;
+ return this;
+ }
+
/**
* To use {@link NormalizedNode} for creating {@link DataNode}.
* @param normalizedNodeTree used for creating the Data Node
* @return this {@link DataNodeBuilder} object
*/
- public DataNodeBuilder withNormalizedNodeTree(final NormalizedNode<?, ?> normalizedNodeTree) {
+ public DataNodeBuilder withNormalizedNodeTree(final NormalizedNode normalizedNodeTree) {
this.normalizedNodeTree = normalizedNodeTree;
return this;
}
return this;
}
+ /**
+ * To use module name for prefix for creating {@link DataNode}.
+ *
+ * @param moduleNamePrefix module name as prefix
+ * @return DataNodeBuilder
+ */
+ public DataNodeBuilder withModuleNamePrefix(final String moduleNamePrefix) {
+ this.moduleNamePrefix = moduleNamePrefix;
+ return this;
+ }
+
+ /**
+ * To use attributes for creating {@link DataNode}.
+ *
+ * @param leaves for the data node
+ * @return DataNodeBuilder
+ */
+ public DataNodeBuilder withLeaves(final Map<String, Serializable> leaves) {
+ this.leaves = leaves;
+ return this;
+ }
+
/**
* To specify child nodes needs to be used while creating {@link DataNode}.
*
}
}
+ /**
+ * To build a {@link Collection} of {@link DataNode} objects.
+ *
+ * @return {@link DataNode} {@link Collection}
+ */
+ public Collection<DataNode> buildCollection() {
+ if (normalizedNodeTree != null) {
+ return buildCollectionFromNormalizedNodeTree();
+ } else {
+ return Set.of(buildFromAttributes());
+ }
+ }
+
private DataNode buildFromAttributes() {
- final DataNode dataNode = new DataNode();
+ final var dataNode = new DataNode();
dataNode.setXpath(xpath);
+ dataNode.setModuleNamePrefix(moduleNamePrefix);
+ dataNode.setLeaves(leaves);
dataNode.setChildDataNodes(childDataNodes);
return dataNode;
}
private DataNode buildFromNormalizedNodeTree() {
- final DataNode formalRootDataNode = new DataNodeBuilder().withXpath("").build();
- addDataNodeFromNormalizedNode(formalRootDataNode, normalizedNodeTree);
- return formalRootDataNode.getChildDataNodes().iterator().next();
+ final Collection<DataNode> dataNodeCollection = buildCollectionFromNormalizedNodeTree();
+ if (!dataNodeCollection.iterator().hasNext()) {
+ throw new DataValidationException(
+ "Unsupported xpath: ", "Unsupported xpath as it is referring to one element");
+ }
+ return dataNodeCollection.iterator().next();
+ }
+
+ private Collection<DataNode> buildCollectionFromNormalizedNodeTree() {
+ final var parentDataNode = new DataNodeBuilder().withXpath(parentNodeXpath).build();
+ addDataNodeFromNormalizedNode(parentDataNode, normalizedNodeTree);
+ return parentDataNode.getChildDataNodes();
}
private static void addDataNodeFromNormalizedNode(final DataNode currentDataNode,
- final NormalizedNode<?, ?> normalizedNode) {
+ final NormalizedNode normalizedNode) {
- if (normalizedNode instanceof DataContainerNode) {
- addYangContainer(currentDataNode, (DataContainerNode<?>) normalizedNode);
+ if (normalizedNode instanceof ChoiceNode) {
+ addChoiceNode(currentDataNode, (ChoiceNode) normalizedNode);
+ } else if (normalizedNode instanceof DataContainerNode) {
+ addYangContainer(currentDataNode, (DataContainerNode) normalizedNode);
} else if (normalizedNode instanceof MapNode) {
addDataNodeForEachListElement(currentDataNode, (MapNode) normalizedNode);
} else if (normalizedNode instanceof ValueNode) {
- final ValueNode<?, ?> valuesNode = (ValueNode<?, ?>) normalizedNode;
- addYangLeaf(currentDataNode, valuesNode.getNodeType().getLocalName(), valuesNode.getValue());
+ final ValueNode<NormalizedNode> valuesNode = (ValueNode) normalizedNode;
+ addYangLeaf(currentDataNode, valuesNode.getIdentifier().getNodeType().getLocalName(),
+ (Serializable) valuesNode.body());
} else if (normalizedNode instanceof LeafSetNode) {
addYangLeafList(currentDataNode, (LeafSetNode<?>) normalizedNode);
} else {
}
}
- private static void addYangContainer(final DataNode currentDataNode, final DataContainerNode<?> dataContainerNode) {
- final DataNode dataContainerDataNode = createAndAddChildDataNode(currentDataNode,
- YangUtils.buildXpath(dataContainerNode.getIdentifier()));
- final Collection<DataContainerChild<?, ?>> normalizedChildNodes = dataContainerNode.getValue();
- for (final NormalizedNode<?, ?> normalizedNode : normalizedChildNodes) {
+ private static void addYangContainer(final DataNode currentDataNode, final DataContainerNode dataContainerNode) {
+ final DataNode dataContainerDataNode =
+ (dataContainerNode.getIdentifier() instanceof YangInstanceIdentifier.AugmentationIdentifier)
+ ? currentDataNode
+ : createAndAddChildDataNode(currentDataNode, YangUtils.buildXpath(dataContainerNode.getIdentifier()));
+ final Collection<DataContainerChild> normalizedChildNodes = dataContainerNode.body();
+ for (final NormalizedNode normalizedNode : normalizedChildNodes) {
addDataNodeFromNormalizedNode(dataContainerDataNode, normalizedNode);
}
}
- private static void addYangLeaf(final DataNode currentDataNode, final String leafName, final Object leafValue) {
- final Map<String, Object> leaves = new ImmutableMap.Builder<String, Object>()
+ private static void addYangLeaf(final DataNode currentDataNode, final String leafName,
+ final Serializable leafValue) {
+ final Map<String, Serializable> leaves = new ImmutableMap.Builder<String, Serializable>()
.putAll(currentDataNode.getLeaves())
.put(leafName, leafValue)
.build();
}
private static void addYangLeafList(final DataNode currentDataNode, final LeafSetNode<?> leafSetNode) {
- final String leafListName = leafSetNode.getNodeType().getLocalName();
- final List<?> leafListValues = ((Collection<? extends NormalizedNode<?, ?>>) leafSetNode.getValue())
- .stream()
- .map(normalizedNode -> ((ValueNode<?, ?>) normalizedNode).getValue())
- .collect(Collectors.toUnmodifiableList());
- addYangLeaf(currentDataNode, leafListName, leafListValues);
+ final String leafListName = leafSetNode.getIdentifier().getNodeType().getLocalName();
+ final List<?> leafListValues = ((Collection<? extends NormalizedNode>) leafSetNode.body())
+ .stream()
+ .map(normalizedNode -> (normalizedNode).body())
+ .collect(Collectors.toUnmodifiableList());
+ addYangLeaf(currentDataNode, leafListName, (Serializable) leafListValues);
}
private static void addDataNodeForEachListElement(final DataNode currentDataNode, final MapNode mapNode) {
- final Collection<MapEntryNode> mapEntryNodes = mapNode.getValue();
+ final Collection<MapEntryNode> mapEntryNodes = mapNode.body();
for (final MapEntryNode mapEntryNode : mapEntryNodes) {
addDataNodeFromNormalizedNode(currentDataNode, mapEntryNode);
}
private static DataNode createAndAddChildDataNode(final DataNode parentDataNode, final String childXpath) {
- final DataNode newChildDataNode = new DataNodeBuilder()
+ final var newChildDataNode = new DataNodeBuilder()
.withXpath(parentDataNode.getXpath() + childXpath)
.build();
final Set<DataNode> allChildDataNodes = new ImmutableSet.Builder<DataNode>()
return newChildDataNode;
}
+ private static void addChoiceNode(final DataNode currentDataNode, final ChoiceNode choiceNode) {
+
+ final Collection<DataContainerChild> normalizedChildNodes = choiceNode.body();
+ for (final NormalizedNode normalizedNode : normalizedChildNodes) {
+ addDataNodeFromNormalizedNode(currentDataNode, normalizedNode);
+ }
+ }
+
+
}