+ @SuppressWarnings({"rawtypes", "unchecked"})
+ @Override
+ public final NormalizedNodeContainer<?, ?, ?> normalize(
+ final QName nodeType, final Node node) {
+ checkArgument(node != null);
+
+ if (!node.getType().equals(AugmentationNode.class.getSimpleName())
+ && !node.getType().equals(ContainerNode.class.getSimpleName())
+ && !node.getType().equals(MapNode.class.getSimpleName())) {
+ checkArgument(nodeType != null);
+ }
+
+ NormalizedNodeContainerBuilder builder = createBuilder(node);
+
+ Set<NodeToNormalizedNodeBuilder<?>> usedMixins = new HashSet<>();
+
+ logNode(node);
+
+ if (node.getChildCount() == 0 && (
+ node.getType().equals(LeafSetEntryNode.class.getSimpleName())
+ || node.getType().equals(LeafNode.class.getSimpleName()))) {
+ PathArgument childPathArgument =
+ NodeIdentifierFactory.getArgument(node.getPath());
+
+ final NormalizedNode child;
+ if (childPathArgument instanceof NodeWithValue) {
+ final NodeWithValue nodeWithValue =
+ new NodeWithValue(childPathArgument.getNodeType(),
+ node.getValue());
+ child =
+ Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(nodeWithValue)
+ .withValue(node.getValue()).build();
+ } else {
+ child =
+ ImmutableNodes.leafNode(childPathArgument.getNodeType(),
+ node.getValue());
+ }
+ builder.addChild(child);
+ }
+
+ final List<Node> children = node.getChildList();
+ for (Node nodeChild : children) {
+
+ PathArgument childPathArgument =
+ NodeIdentifierFactory.getArgument(nodeChild.getPath());
+
+ QName childNodeType = null;
+ NodeToNormalizedNodeBuilder childOp = null;
+
+ if (childPathArgument instanceof AugmentationIdentifier) {
+ childOp = getChild(childPathArgument);
+ checkArgument(childOp instanceof AugmentationNormalization, childPathArgument);
+ } else {
+ childNodeType = childPathArgument.getNodeType();
+ childOp = getChild(childNodeType);
+ }
+ // We skip unknown nodes if this node is mixin since
+ // it's nodes and parent nodes are interleaved
+ if (childOp == null && isMixin()) {
+ continue;
+ } else if (childOp == null) {
+ logger.error(
+ "childOp is null and this operation is not a mixin : this = {}",
+ this.toString());
+ }
+
+ checkArgument(childOp != null,
+ "Node %s is not allowed inside %s",
+ childNodeType, getIdentifier());
+
+ if (childOp.isMixin()) {
+ if (usedMixins.contains(childOp)) {
+ // We already run / processed that mixin, so to avoid
+ // duplicate we are
+ // skipping next nodes.
+ continue;
+ }
+ // builder.addChild(childOp.normalize(nodeType, treeCacheNode));
+ final NormalizedNode childNode =
+ childOp.normalize(childNodeType, nodeChild);
+ if (childNode != null)
+ builder.addChild(childNode);
+ usedMixins.add(childOp);
+ } else {
+ final NormalizedNode childNode =
+ childOp.normalize(childNodeType, nodeChild);
+ if (childNode != null)
+ builder.addChild(childNode);
+ }
+ }
+
+
+ try {
+ return (NormalizedNodeContainer<?, ?, ?>) builder.build();
+ } catch (Exception e) {
+ return null;
+ }