X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-protocolbuffer-encoding%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2Fnode%2FNodeToNormalizedNodeBuilder.java;h=03d632b61fb7070d568e360bcd7494ed40c59041;hp=b0ba487177b7d1004b08d5645661c8d76ac55614;hb=69eca29208f36b9a02992319cc36d1d221189ff0;hpb=1e59825dbec7b354d76bd7efa6a61e4ad802c802 diff --git a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java index b0ba487177..03d632b61f 100644 --- a/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java +++ b/opendaylight/md-sal/sal-protocolbuffer-encoding/src/main/java/org/opendaylight/controller/cluster/datastore/node/NodeToNormalizedNodeBuilder.java @@ -1,3 +1,13 @@ +/* + * + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + package org.opendaylight.controller.cluster.datastore.node; import com.google.common.base.Preconditions; @@ -8,14 +18,17 @@ import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFa import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -48,7 +61,7 @@ import static com.google.common.base.Preconditions.checkArgument; /** * NormalizedNodeBuilder is a builder that walks through a tree like structure and constructs a * NormalizedNode from it. - * + *

* A large part of this code has been copied over from a similar class in sal-common-impl which was * originally supposed to convert a CompositeNode to NormalizedNode * @@ -57,694 +70,787 @@ import static com.google.common.base.Preconditions.checkArgument; public abstract class NodeToNormalizedNodeBuilder implements Identifiable { - private final T identifier; + private final T identifier; - protected static final Logger logger = LoggerFactory - .getLogger(NodeToNormalizedNodeBuilder.class); + protected static final Logger logger = LoggerFactory + .getLogger(NodeToNormalizedNodeBuilder.class); - @Override - public T getIdentifier() { - return identifier; - }; + @Override + public T getIdentifier() { + return identifier; + } - protected NodeToNormalizedNodeBuilder(final T identifier) { - super(); - this.identifier = identifier; + ; - } + protected NodeToNormalizedNodeBuilder(final T identifier) { + super(); + this.identifier = identifier; - /** - * - * @return Should return true if the node that this operation corresponds to is a mixin - */ - public boolean isMixin() { - return false; - } + } + /** + * @return Should return true if the node that this operation corresponds to is a mixin + */ + public boolean isMixin() { + return false; + } - /** - * - * @return Should return true if the node that this operation corresponds to has a 'key' - * associated with it. This is typically true for a list-item or leaf-list entry in yang - */ - public boolean isKeyedEntry() { - return false; - } - protected Set getQNameIdentifiers() { - return Collections.singleton(identifier.getNodeType()); - } + /** + * @return Should return true if the node that this operation corresponds to has a 'key' + * associated with it. This is typically true for a list-item or leaf-list entry in yang + */ + public boolean isKeyedEntry() { + return false; + } - public abstract NodeToNormalizedNodeBuilder getChild( - final PathArgument child); + protected Set getQNameIdentifiers() { + return Collections.singleton(identifier.getNodeType()); + } - public abstract NodeToNormalizedNodeBuilder getChild(QName child); + public abstract NodeToNormalizedNodeBuilder getChild( + final PathArgument child); - public abstract NormalizedNode normalize(QName nodeType, Node node); + public abstract NodeToNormalizedNodeBuilder getChild(QName child); + public abstract NormalizedNode normalize(QName nodeType, Node node); - private static abstract class SimpleTypeNormalization - extends NodeToNormalizedNodeBuilder { - protected SimpleTypeNormalization(final T identifier) { - super(identifier); - } + private static abstract class SimpleTypeNormalization + extends NodeToNormalizedNodeBuilder { - @Override - public NormalizedNode normalize(final QName nodeType, final Node node) { - checkArgument(node != null); - return normalizeImpl(nodeType, node); - } + protected SimpleTypeNormalization(final T identifier) { + super(identifier); + } - protected abstract NormalizedNode normalizeImpl(QName nodeType, - Node node); + @Override + public NormalizedNode normalize(final QName nodeType, + final Node node) { + checkArgument(node != null); + return normalizeImpl(nodeType, node); + } - @Override - public NodeToNormalizedNodeBuilder getChild(final PathArgument child) { - return null; - } + protected abstract NormalizedNode normalizeImpl(QName nodeType, + Node node); - @Override - public NodeToNormalizedNodeBuilder getChild(final QName child) { - return null; - } + @Override + public NodeToNormalizedNodeBuilder getChild( + final PathArgument child) { + return null; + } + + @Override + public NodeToNormalizedNodeBuilder getChild(final QName child) { + return null; + } + + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + // TODO Auto-generated method stub + return null; + } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - // TODO Auto-generated method stub - return null; } - } - private static final class LeafNormalization extends - SimpleTypeNormalization { + private static final class LeafNormalization extends + SimpleTypeNormalization { - protected LeafNormalization(final NodeIdentifier identifier) { - super(identifier); - } + private final LeafSchemaNode schema; - @Override - protected NormalizedNode normalizeImpl(final QName nodeType, - final Node node) { - return ImmutableNodes.leafNode(nodeType, node.getValue()); + protected LeafNormalization(final LeafSchemaNode schema, final NodeIdentifier identifier) { + super(identifier); + this.schema = schema; + } + + @Override + protected NormalizedNode normalizeImpl(final QName nodeType, + final Node node) { + Object value = NodeValueCodec.toTypeSafeValue(this.schema, this.schema.getType(), node); + return ImmutableNodes.leafNode(nodeType, value); + + } } - } - private static final class LeafListEntryNormalization extends - SimpleTypeNormalization { + private static final class LeafListEntryNormalization extends + SimpleTypeNormalization { - public LeafListEntryNormalization(final LeafListSchemaNode potential) { - super(new NodeWithValue(potential.getQName(), null)); - } + private final LeafListSchemaNode schema; - @Override - protected NormalizedNode normalizeImpl(final QName nodeType, - final Node node) { - final Object data = node.getValue(); - if (data == null) { - Preconditions.checkArgument(false, - "No data available in leaf list entry for " + nodeType); - } - NodeWithValue nodeId = new NodeWithValue(nodeType, data); - return Builders.leafSetEntryBuilder().withNodeIdentifier(nodeId) - .withValue(data).build(); - } + public LeafListEntryNormalization(final LeafListSchemaNode potential) { + super(new NodeWithValue(potential.getQName(), null)); + this.schema = potential; + } + @Override + protected NormalizedNode normalizeImpl(final QName nodeType, + final Node node) { + final Object data = node.getValue(); + if (data == null) { + Preconditions.checkArgument(false, + "No data available in leaf list entry for " + nodeType); + } - @Override - public boolean isKeyedEntry() { - return true; - } - } + Object value = NodeValueCodec.toTypeSafeValue(this.schema, this.schema.getType(), node); - private static abstract class NodeToNormalizationNodeOperation - extends NodeToNormalizedNodeBuilder { + NodeWithValue nodeId = new NodeWithValue(nodeType, value); + return Builders.leafSetEntryBuilder().withNodeIdentifier(nodeId) + .withValue(value).build(); + } - protected NodeToNormalizationNodeOperation(final T identifier) { - super(identifier); - } - @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())) { - checkArgument(nodeType != null); - } - - NormalizedNodeContainerBuilder builder = createBuilder(node); - - Set> usedMixins = new HashSet<>(); - - logNode(node); - - if (node.getChildCount() == 0 && !node.getType().equals(ContainerNode.class.getSimpleName())) { - PathArgument childPathArgument = - NodeIdentifierFactory.getArgument(node.getPath()); - NormalizedNode child = null; - 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()); + @Override + public boolean isKeyedEntry() { + return true; } - builder.addChild(child); - } + } - final List children = node.getChildList(); - for (Node nodeChild : children) { - PathArgument childPathArgument = - NodeIdentifierFactory.getArgument(nodeChild.getPath()); + private static abstract class NodeToNormalizationNodeOperation + extends NodeToNormalizedNodeBuilder { - QName childNodeType = null; - NodeToNormalizedNodeBuilder childOp = null; + protected NodeToNormalizationNodeOperation(final T identifier) { + super(identifier); + } + @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> 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 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; + } - if (childPathArgument instanceof AugmentationIdentifier) { - childOp = getChild(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 - // skiping 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); } - } + private void logNode(Node node) { + //let us find out the type of the node + logger.debug("We got a {} , with identifier {} with {} children", + node.getType(), node.getPath(), + node.getChildList()); + } - try { - return (NormalizedNodeContainer) builder.build(); - } catch (Exception e) { - return null; - } + @SuppressWarnings("rawtypes") + protected abstract NormalizedNodeContainerBuilder createBuilder( + final Node node); } - private void logNode(Node node) { - //let us find out the type of the node - logger.debug("We got a {} , with identifier {} with {} children", node.getType(),node.getPath(), - node.getChildList()); - } - @SuppressWarnings("rawtypes") - protected abstract NormalizedNodeContainerBuilder createBuilder( - final Node node); + private static abstract class DataContainerNormalizationOperation + extends NodeToNormalizationNodeOperation { - } + private final DataNodeContainer schema; + private final Map> byQName; + private final Map> byArg; - private static abstract class DataContainerNormalizationOperation - extends NodeToNormalizationNodeOperation { + protected DataContainerNormalizationOperation(final T identifier, + final DataNodeContainer schema) { + super(identifier); + this.schema = schema; + this.byArg = new ConcurrentHashMap<>(); + this.byQName = new ConcurrentHashMap<>(); + } - private final DataNodeContainer schema; - private final Map> byQName; - private final Map> byArg; + @Override + public NodeToNormalizedNodeBuilder getChild( + final PathArgument child) { + NodeToNormalizedNodeBuilder potential = byArg.get(child); + if (potential != null) { + return potential; + } + potential = fromSchema(schema, child); + return register(potential); + } - protected DataContainerNormalizationOperation(final T identifier, - final DataNodeContainer schema) { - super(identifier); - this.schema = schema; - this.byArg = new ConcurrentHashMap<>(); - this.byQName = new ConcurrentHashMap<>(); - } + @Override + public NodeToNormalizedNodeBuilder getChild(final QName child) { + if (child == null) { + return null; + } + + NodeToNormalizedNodeBuilder potential = byQName.get(child); + if (potential != null) { + return potential; + } + potential = fromSchemaAndPathArgument(schema, child); + return register(potential); + } - @Override - public NodeToNormalizedNodeBuilder getChild(final PathArgument child) { - NodeToNormalizedNodeBuilder potential = byArg.get(child); - if (potential != null) { - return potential; - } - potential = fromSchema(schema, child); - return register(potential); - } + private NodeToNormalizedNodeBuilder register( + final NodeToNormalizedNodeBuilder potential) { + if (potential != null) { + byArg.put(potential.getIdentifier(), potential); + for (QName qName : potential.getQNameIdentifiers()) { + byQName.put(qName, potential); + } + } + return potential; + } - @Override - public NodeToNormalizedNodeBuilder getChild(final QName child) { - if (child == null) { - return null; - } - - NodeToNormalizedNodeBuilder potential = byQName.get(child); - if (potential != null) { - return potential; - } - potential = fromSchemaAndPathArgument(schema, child); - return register(potential); } - private NodeToNormalizedNodeBuilder register( - final NodeToNormalizedNodeBuilder potential) { - if (potential != null) { - byArg.put(potential.getIdentifier(), potential); - for (QName qName : potential.getQNameIdentifiers()) { - byQName.put(qName, potential); + + private static final class ListItemNormalization extends + DataContainerNormalizationOperation { + + private final List keyDefinition; + private final ListSchemaNode schemaNode; + + protected ListItemNormalization( + final NodeIdentifierWithPredicates identifier, + final ListSchemaNode schema) { + super(identifier, schema); + this.schemaNode = schema; + keyDefinition = schema.getKeyDefinition(); } - } - return potential; - } - } + @Override + protected NormalizedNodeContainerBuilder createBuilder( + final Node node) { + NodeIdentifierWithPredicates nodeIdentifierWithPredicates = + (NodeIdentifierWithPredicates) NodeIdentifierFactory + .createPathArgument(node + .getPath(), schemaNode); + return Builders.mapEntryBuilder() + .withNodeIdentifier( + nodeIdentifierWithPredicates + ); + } - private static final class ListItemNormalization extends - DataContainerNormalizationOperation { + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + DataContainerNodeAttrBuilder + builder = + Builders.mapEntryBuilder().withNodeIdentifier( + (NodeIdentifierWithPredicates) currentArg); + for (Entry keyValue : ((NodeIdentifierWithPredicates) currentArg) + .getKeyValues().entrySet()) { + if (keyValue.getValue() == null) { + throw new NullPointerException( + "Null value found for path : " + + currentArg); + } + builder.addChild(Builders.leafBuilder() + // + .withNodeIdentifier(new NodeIdentifier(keyValue.getKey())) + .withValue(keyValue.getValue()).build()); + } + return builder.build(); + } - private final List keyDefinition; - private final ListSchemaNode schemaNode; - protected ListItemNormalization( - final NodeIdentifierWithPredicates identifier, - final ListSchemaNode schema) { - super(identifier, schema); - this.schemaNode = schema; - keyDefinition = schema.getKeyDefinition(); + @Override + public boolean isKeyedEntry() { + return true; + } } - @Override - protected NormalizedNodeContainerBuilder createBuilder(final Node node) { - return Builders.mapEntryBuilder().withNodeIdentifier( - (NodeIdentifierWithPredicates) NodeIdentifierFactory.getArgument(node - .getPath())); - } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - DataContainerNodeAttrBuilder builder = - Builders.mapEntryBuilder().withNodeIdentifier( - (NodeIdentifierWithPredicates) currentArg); - for (Entry keyValue : ((NodeIdentifierWithPredicates) currentArg) - .getKeyValues().entrySet()) { - if (keyValue.getValue() == null) { - throw new NullPointerException("Null value found for path : " - + currentArg); - } - builder.addChild(Builders.leafBuilder() - // - .withNodeIdentifier(new NodeIdentifier(keyValue.getKey())) - .withValue(keyValue.getValue()).build()); - } - return builder.build(); - } + private static final class ContainerNormalization extends + DataContainerNormalizationOperation { + protected ContainerNormalization(final ContainerSchemaNode schema) { + super(new NodeIdentifier(schema.getQName()), schema); + } - @Override - public boolean isKeyedEntry() { - return true; - } - } + @Override + protected NormalizedNodeContainerBuilder createBuilder( + final Node node) { + return Builders.containerBuilder() + .withNodeIdentifier(getIdentifier()); + } - private static final class ContainerNormalization extends - DataContainerNormalizationOperation { + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + return Builders.containerBuilder() + .withNodeIdentifier((NodeIdentifier) currentArg).build(); + } - protected ContainerNormalization(final ContainerSchemaNode schema) { - super(new NodeIdentifier(schema.getQName()), schema); } - @Override - protected NormalizedNodeContainerBuilder createBuilder(final Node node) { - return Builders.containerBuilder().withNodeIdentifier(getIdentifier()); - } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - return Builders.containerBuilder() - .withNodeIdentifier((NodeIdentifier) currentArg).build(); - } + private static abstract class MixinNormalizationOp + extends NodeToNormalizationNodeOperation { - } + protected MixinNormalizationOp(final T identifier) { + super(identifier); + } - private static abstract class MixinNormalizationOp - extends NodeToNormalizationNodeOperation { + @Override + public final boolean isMixin() { + return true; + } - protected MixinNormalizationOp(final T identifier) { - super(identifier); } - @Override - public final boolean isMixin() { - return true; - } - } + private static final class LeafListMixinNormalization extends + MixinNormalizationOp { - private static final class LeafListMixinNormalization extends - MixinNormalizationOp { + private final NodeToNormalizedNodeBuilder innerOp; - private final NodeToNormalizedNodeBuilder innerOp; + public LeafListMixinNormalization(final LeafListSchemaNode potential) { + super(new NodeIdentifier(potential.getQName())); + innerOp = new LeafListEntryNormalization(potential); + } - public LeafListMixinNormalization(final LeafListSchemaNode potential) { - super(new NodeIdentifier(potential.getQName())); - innerOp = new LeafListEntryNormalization(potential); - } + @Override + protected NormalizedNodeContainerBuilder createBuilder( + final Node node) { + return Builders.leafSetBuilder() + .withNodeIdentifier(getIdentifier()); + } - @Override - protected NormalizedNodeContainerBuilder createBuilder( - final Node node) { - return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()); - } + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()) + .build(); + } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()) - .build(); - } + @Override + public NodeToNormalizedNodeBuilder getChild( + final PathArgument child) { + if (child instanceof NodeWithValue) { + return innerOp; + } + return null; + } - @Override - public NodeToNormalizedNodeBuilder getChild(final PathArgument child) { - if (child instanceof NodeWithValue) { - return innerOp; - } - return null; - } + @Override + public NodeToNormalizedNodeBuilder getChild(final QName child) { + if (getIdentifier().getNodeType().equals(child)) { + return innerOp; + } + return null; + } - @Override - public NodeToNormalizedNodeBuilder getChild(final QName child) { - if (getIdentifier().getNodeType().equals(child)) { - return innerOp; - } - return null; } - } - private static final class AugmentationNormalization extends - MixinNormalizationOp { + private static final class AugmentationNormalization extends + MixinNormalizationOp { - private final Map> byQName; - private final Map> byArg; + private final Map> byQName; + private final Map> byArg; - public AugmentationNormalization(final AugmentationSchema augmentation, - final DataNodeContainer schema) { - super(augmentationIdentifierFrom(augmentation)); + public AugmentationNormalization(final AugmentationSchema augmentation, + final DataNodeContainer schema) { + super(augmentationIdentifierFrom(augmentation)); - ImmutableMap.Builder> byQNameBuilder = - ImmutableMap.builder(); - ImmutableMap.Builder> byArgBuilder = - ImmutableMap.builder(); + ImmutableMap.Builder> + byQNameBuilder = + ImmutableMap.builder(); + ImmutableMap.Builder> + byArgBuilder = + ImmutableMap.builder(); + + for (DataSchemaNode augNode : augmentation.getChildNodes()) { + DataSchemaNode resolvedNode = + schema.getDataChildByName(augNode.getQName()); + NodeToNormalizedNodeBuilder resolvedOp = + fromDataSchemaNode(resolvedNode); + byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp); + for (QName resQName : resolvedOp.getQNameIdentifiers()) { + byQNameBuilder.put(resQName, resolvedOp); + } + } + byQName = byQNameBuilder.build(); + byArg = byArgBuilder.build(); - for (DataSchemaNode augNode : augmentation.getChildNodes()) { - DataSchemaNode resolvedNode = - schema.getDataChildByName(augNode.getQName()); - NodeToNormalizedNodeBuilder resolvedOp = - fromDataSchemaNode(resolvedNode); - byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp); - for (QName resQName : resolvedOp.getQNameIdentifiers()) { - byQNameBuilder.put(resQName, resolvedOp); } - } - byQName = byQNameBuilder.build(); - byArg = byArgBuilder.build(); - } + @Override + public NodeToNormalizedNodeBuilder getChild( + final PathArgument child) { + return byArg.get(child); + } - @Override - public NodeToNormalizedNodeBuilder getChild(final PathArgument child) { - return byArg.get(child); - } + @Override + public NodeToNormalizedNodeBuilder getChild(final QName child) { + return byQName.get(child); + } - @Override - public NodeToNormalizedNodeBuilder getChild(final QName child) { - return byQName.get(child); - } + @Override + protected Set getQNameIdentifiers() { + return getIdentifier().getPossibleChildNames(); + } - @Override - protected Set getQNameIdentifiers() { - return getIdentifier().getPossibleChildNames(); - } + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder( + final Node node) { + return Builders.augmentationBuilder() + .withNodeIdentifier(getIdentifier()); + } - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final Node node) { - return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier()); - } + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + return Builders.augmentationBuilder() + .withNodeIdentifier(getIdentifier()) + .build(); + } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier()) - .build(); } - } - private static final class ListMixinNormalization extends - MixinNormalizationOp { + private static final class ListMixinNormalization extends + MixinNormalizationOp { - private final ListItemNormalization innerNode; + private final ListItemNormalization innerNode; - public ListMixinNormalization(final ListSchemaNode list) { - super(new NodeIdentifier(list.getQName())); - this.innerNode = - new ListItemNormalization(new NodeIdentifierWithPredicates( - list.getQName(), Collections.emptyMap()), list); - } + public ListMixinNormalization(final ListSchemaNode list) { + super(new NodeIdentifier(list.getQName())); + this.innerNode = + new ListItemNormalization(new NodeIdentifierWithPredicates( + list.getQName(), Collections.emptyMap()), + list); + } - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder( - final Node node) { - return Builders.mapBuilder().withNodeIdentifier(getIdentifier()); - } + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder( + final Node node) { + return Builders.mapBuilder().withNodeIdentifier(getIdentifier()); + } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - return Builders.mapBuilder().withNodeIdentifier(getIdentifier()).build(); - } + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + return Builders.mapBuilder().withNodeIdentifier(getIdentifier()) + .build(); + } - @Override - public NodeToNormalizedNodeBuilder getChild(final PathArgument child) { - if (child.getNodeType().equals(getIdentifier().getNodeType())) { - return innerNode; - } - return null; - } + @Override + public NodeToNormalizedNodeBuilder getChild( + final PathArgument child) { + if (child.getNodeType().equals(getIdentifier().getNodeType())) { + return innerNode; + } + return null; + } - @Override - public NodeToNormalizedNodeBuilder getChild(final QName child) { - if (getIdentifier().getNodeType().equals(child)) { - return innerNode; - } - return null; - } + @Override + public NodeToNormalizedNodeBuilder getChild(final QName child) { + if (getIdentifier().getNodeType().equals(child)) { + return innerNode; + } + return null; + } - } - - private static class ChoiceNodeNormalization extends - MixinNormalizationOp { - - private final ImmutableMap> byQName; - private final ImmutableMap> byArg; - - protected ChoiceNodeNormalization( - final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) { - super(new NodeIdentifier(schema.getQName())); - ImmutableMap.Builder> byQNameBuilder = - ImmutableMap.builder(); - ImmutableMap.Builder> byArgBuilder = - ImmutableMap.builder(); - - for (ChoiceCaseNode caze : schema.getCases()) { - for (DataSchemaNode cazeChild : caze.getChildNodes()) { - NodeToNormalizedNodeBuilder childOp = - fromDataSchemaNode(cazeChild); - byArgBuilder.put(childOp.getIdentifier(), childOp); - for (QName qname : childOp.getQNameIdentifiers()) { - byQNameBuilder.put(qname, childOp); - } - } - } - byQName = byQNameBuilder.build(); - byArg = byArgBuilder.build(); } - @Override - public NodeToNormalizedNodeBuilder getChild(final PathArgument child) { - return byArg.get(child); - } - @Override - public NodeToNormalizedNodeBuilder getChild(final QName child) { - return byQName.get(child); - } + private static class ChoiceNodeNormalization extends + MixinNormalizationOp { + + private final ImmutableMap> + byQName; + private final ImmutableMap> + byArg; + + protected ChoiceNodeNormalization( + final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) { + super(new NodeIdentifier(schema.getQName())); + ImmutableMap.Builder> + byQNameBuilder = + ImmutableMap.builder(); + ImmutableMap.Builder> + byArgBuilder = + ImmutableMap.builder(); + + for (ChoiceCaseNode caze : schema.getCases()) { + for (DataSchemaNode cazeChild : caze.getChildNodes()) { + NodeToNormalizedNodeBuilder childOp = + fromDataSchemaNode(cazeChild); + byArgBuilder.put(childOp.getIdentifier(), childOp); + for (QName qname : childOp.getQNameIdentifiers()) { + byQNameBuilder.put(qname, childOp); + } + } + } + byQName = byQNameBuilder.build(); + byArg = byArgBuilder.build(); + } - @Override - protected NormalizedNodeContainerBuilder createBuilder(final Node node) { - return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()); - } + @Override + public NodeToNormalizedNodeBuilder getChild( + final PathArgument child) { + return byArg.get(child); + } - @Override - public NormalizedNode createDefault(final PathArgument currentArg) { - return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()) - .build(); - } - } - - public static NodeToNormalizedNodeBuilder fromSchemaAndPathArgument( - final DataNodeContainer schema, final QName child) { - DataSchemaNode potential = schema.getDataChildByName(child); - if (potential == null) { - Iterable choices = - FluentIterable.from(schema.getChildNodes()).filter( - org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); - potential = findChoice(choices, child); - } - if (potential == null) { - if (logger.isTraceEnabled()) { - logger.trace("BAD CHILD = {}", child.toString()); - } - } + @Override + public NodeToNormalizedNodeBuilder getChild(final QName child) { + return byQName.get(child); + } - checkArgument(potential != null, - "Supplied QName %s is not valid according to schema %s", child, schema); - if ((schema instanceof DataSchemaNode) - && !((DataSchemaNode) schema).isAugmenting() - && potential.isAugmenting()) { - return fromAugmentation(schema, (AugmentationTarget) schema, potential); - } - return fromDataSchemaNode(potential); - } - - /** - * Given a bunch of choice nodes and a the name of child find a choice node for that child which - * has a non-null value - * - * @param choices - * @param child - * @return - */ - private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice( - final Iterable choices, - final QName child) { - org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null; - choiceLoop: for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) { - for (ChoiceCaseNode caze : choice.getCases()) { - if (caze.getDataChildByName(child) != null) { - foundChoice = choice; - break choiceLoop; - } - } - } - return foundChoice; - } - - - /** - * Create an AugmentationIdentifier based on the AugmentationSchema - * - * @param augmentation - * @return - */ - public static AugmentationIdentifier augmentationIdentifierFrom( - final AugmentationSchema augmentation) { - ImmutableSet.Builder potentialChildren = ImmutableSet.builder(); - for (DataSchemaNode child : augmentation.getChildNodes()) { - potentialChildren.add(child.getQName()); - } - return new AugmentationIdentifier(null, potentialChildren.build()); - } - - /** - * Create an AugmentationNormalization based on the schema of the DataContainer, the - * AugmentationTarget and the potential schema node - * - * @param schema - * @param augments - * @param potential - * @return - */ - private static AugmentationNormalization fromAugmentation( - final DataNodeContainer schema, final AugmentationTarget augments, - final DataSchemaNode potential) { - AugmentationSchema augmentation = null; - for (AugmentationSchema aug : augments.getAvailableAugmentations()) { - DataSchemaNode child = aug.getDataChildByName(potential.getQName()); - if (child != null) { - augmentation = aug; - break; - } + @Override + protected NormalizedNodeContainerBuilder createBuilder( + final Node node) { + return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()); + } + @Override + public NormalizedNode createDefault( + final PathArgument currentArg) { + return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()) + .build(); + } } - if (augmentation != null) { - return new AugmentationNormalization(augmentation, schema); - } else { - return null; + + /** + * Find an appropriate NormalizedNodeBuilder using both the schema and the + * Path Argument + * + * @param schema + * @param child + * @return + */ + public static NodeToNormalizedNodeBuilder fromSchemaAndPathArgument( + final DataNodeContainer schema, final QName child) { + DataSchemaNode potential = schema.getDataChildByName(child); + if (potential == null) { + Iterable + choices = + FluentIterable.from(schema.getChildNodes()).filter( + org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); + potential = findChoice(choices, child); + } + if (potential == null) { + if (logger.isTraceEnabled()) { + logger.trace("BAD CHILD = {}", child.toString()); + } + } + + checkArgument(potential != null, + "Supplied QName %s is not valid according to schema %s", child, + schema); + + // If the schema in an instance of DataSchemaNode and the potential + // is augmenting something then there is a chance that this may be + // and augmentation node + if ((schema instanceof DataSchemaNode) + && potential.isAugmenting()) { + + AugmentationNormalization augmentation = + fromAugmentation(schema, (AugmentationTarget) schema, + potential); + + // If an augmentation normalization (builder) is not found then + // we fall through to the regular processing + if(augmentation != null){ + return augmentation; + } + } + return fromDataSchemaNode(potential); + } + + /** + * Given a bunch of choice nodes and a the name of child find a choice node for that child which + * has a non-null value + * + * @param choices + * @param child + * @return + */ + private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice( + final Iterable choices, + final QName child) { + org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null; + choiceLoop: + for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) { + for (ChoiceCaseNode caze : choice.getCases()) { + if (caze.getDataChildByName(child) != null) { + foundChoice = choice; + break choiceLoop; + } + } + } + return foundChoice; } - } - - /** - * - * @param schema - * @param child - * @return - */ - private static NodeToNormalizedNodeBuilder fromSchema( - final DataNodeContainer schema, final PathArgument child) { - if (child instanceof AugmentationIdentifier) { - return fromSchemaAndPathArgument(schema, ((AugmentationIdentifier) child) - .getPossibleChildNames().iterator().next()); + + + /** + * Create an AugmentationIdentifier based on the AugmentationSchema + * + * @param augmentation + * @return + */ + public static AugmentationIdentifier augmentationIdentifierFrom( + final AugmentationSchema augmentation) { + ImmutableSet.Builder potentialChildren = ImmutableSet.builder(); + for (DataSchemaNode child : augmentation.getChildNodes()) { + potentialChildren.add(child.getQName()); + } + return new AugmentationIdentifier(potentialChildren.build()); + } + + /** + * Create an AugmentationNormalization based on the schema of the DataContainer, the + * AugmentationTarget and the potential schema node + * + * @param schema + * @param augments + * @param potential + * @return + */ + private static AugmentationNormalization fromAugmentation( + final DataNodeContainer schema, final AugmentationTarget augments, + final DataSchemaNode potential) { + AugmentationSchema augmentation = null; + for (AugmentationSchema aug : augments.getAvailableAugmentations()) { + DataSchemaNode child = aug.getDataChildByName(potential.getQName()); + if (child != null) { + augmentation = aug; + break; + } + + } + if (augmentation != null) { + return new AugmentationNormalization(augmentation, schema); + } else { + return null; + } } - return fromSchemaAndPathArgument(schema, child.getNodeType()); - } - - public static NodeToNormalizedNodeBuilder fromDataSchemaNode( - final DataSchemaNode potential) { - if (potential instanceof ContainerSchemaNode) { - return new ContainerNormalization((ContainerSchemaNode) potential); - } else if (potential instanceof ListSchemaNode) { - return new ListMixinNormalization((ListSchemaNode) potential); - } else if (potential instanceof LeafSchemaNode) { - return new LeafNormalization(new NodeIdentifier(potential.getQName())); - } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) { - return new ChoiceNodeNormalization( - (org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential); - } else if (potential instanceof LeafListSchemaNode) { - return new LeafListMixinNormalization((LeafListSchemaNode) potential); + + /** + * @param schema + * @param child + * @return + */ + private static NodeToNormalizedNodeBuilder fromSchema( + final DataNodeContainer schema, final PathArgument child) { + if (child instanceof AugmentationIdentifier) { + QName childQName = ((AugmentationIdentifier) child) + .getPossibleChildNames().iterator().next(); + + return fromSchemaAndPathArgument(schema, childQName); + } + return fromSchemaAndPathArgument(schema, child.getNodeType()); + } + + public static NodeToNormalizedNodeBuilder fromDataSchemaNode( + final DataSchemaNode potential) { + if (potential instanceof ContainerSchemaNode) { + return new ContainerNormalization((ContainerSchemaNode) potential); + } else if (potential instanceof ListSchemaNode) { + return new ListMixinNormalization((ListSchemaNode) potential); + } else if (potential instanceof LeafSchemaNode) { + return new LeafNormalization((LeafSchemaNode) potential, + new NodeIdentifier(potential.getQName())); + } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) { + return new ChoiceNodeNormalization( + (org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential); + } else if (potential instanceof LeafListSchemaNode) { + return new LeafListMixinNormalization( + (LeafListSchemaNode) potential); + } + return null; } - return null; - } - public static NodeToNormalizedNodeBuilder from(final SchemaContext ctx) { - return new ContainerNormalization(ctx); - } + public static NodeToNormalizedNodeBuilder from(final SchemaContext ctx) { + return new ContainerNormalization(ctx); + } - public abstract NormalizedNode createDefault(PathArgument currentArg); + public abstract NormalizedNode createDefault(PathArgument currentArg); }