X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Fbuilder%2Fimpl%2FImmutableMapEntryNodeBuilder.java;h=59af23fa5fdfbc57d42eb0142a83ce763583598f;hb=ae6ddca4a6b4a32071f10d480cd037c41a0983b4;hp=93fd66a83c869d14d59351dc32ccfbe93766455d;hpb=eedbf1abb168811cf17d44cce4af736e689288ff;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java index 93fd66a83c..59af23fa5f 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeBuilder.java @@ -7,83 +7,123 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl; -import java.util.List; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.Map; - +import java.util.Map.Entry; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException; import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerAttrNode; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ImmutableMapEntryNodeBuilder - extends AbstractImmutableDataContainerNodeAttrBuilder { - - protected final Map childrenQNamesToPaths; + extends AbstractImmutableDataContainerNodeAttrBuilder { + private static final Logger LOG = LoggerFactory.getLogger(ImmutableMapEntryNodeBuilder.class); + protected final Map childrenQNamesToPaths; protected ImmutableMapEntryNodeBuilder() { - this.childrenQNamesToPaths = Maps.newLinkedHashMap(); + this.childrenQNamesToPaths = new LinkedHashMap<>(); + } + + protected ImmutableMapEntryNodeBuilder(final int sizeHint) { + super(sizeHint); + this.childrenQNamesToPaths = new LinkedHashMap<>(sizeHint); + } + + protected ImmutableMapEntryNodeBuilder(final ImmutableMapEntryNode node) { + super(node); + this.childrenQNamesToPaths = new LinkedHashMap<>(); + fillQnames(node.getValue(), childrenQNamesToPaths); } - public static DataContainerNodeAttrBuilder create() { + public static DataContainerNodeAttrBuilder create() { return new ImmutableMapEntryNodeBuilder(); } - // FIXME, find better solution than 2 maps (map from QName to Child ?) + public static DataContainerNodeAttrBuilder create(final int sizeHint) { + return new ImmutableMapEntryNodeBuilder(sizeHint); + } - @Override - public DataContainerNodeAttrBuilder withValue(final List> value) { - for (final DataContainerChild childId : value) { - final InstanceIdentifier.PathArgument identifier = childId.getIdentifier(); + public static DataContainerNodeAttrBuilder create( + final MapEntryNode node) { + if (!(node instanceof ImmutableMapEntryNode)) { + throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass())); + } + + return new ImmutableMapEntryNodeBuilder((ImmutableMapEntryNode)node); + } + + private static void fillQnames(final Iterable> iterable, + final Map out) { + for (final DataContainerChild childId : iterable) { + final PathArgument identifier = childId.getIdentifier(); // Augmentation nodes cannot be keys, and do not have to be present in childrenQNamesToPaths map - if(identifier instanceof InstanceIdentifier.AugmentationIdentifier) { + if (isAugment(identifier)) { continue; } - this.childrenQNamesToPaths.put(childId.getNodeType(), identifier); + out.put(childId.getNodeType(), identifier); } + } + + + @Override + public DataContainerNodeAttrBuilder withValue( + final Collection> value) { + fillQnames(value, childrenQNamesToPaths); return super.withValue(value); } + private static boolean isAugment(final PathArgument identifier) { + return identifier instanceof AugmentationIdentifier; + } + @Override - public DataContainerNodeAttrBuilder withChild(final DataContainerChild child) { + public DataContainerNodeAttrBuilder withChild( + final DataContainerChild child) { // Augmentation nodes cannot be keys, and do not have to be present in childrenQNamesToPaths map - if(child.getIdentifier() instanceof InstanceIdentifier.AugmentationIdentifier == false) { + if (!isAugment(child.getIdentifier())) { childrenQNamesToPaths.put(child.getNodeType(), child.getIdentifier()); } + return super.withChild(child); } @Override public MapEntryNode build() { - checkKeys(); - return new ImmutableMapEntryNode(getNodeIdentifier(), buildValue(), attributes); - } - - private void checkKeys() { - for (final QName keyQName : getNodeIdentifier().getKeyValues().keySet()) { - - final InstanceIdentifier.PathArgument childNodePath = childrenQNamesToPaths.get(keyQName); - final DataContainerChild childNode = getChild(childNodePath); - - Preconditions.checkNotNull(childNode, "Key child node: %s, not present", keyQName); - - final Object actualValue = getNodeIdentifier().getKeyValues().get(keyQName); - final Object expectedValue = childNode.getValue(); - Preconditions.checkArgument(expectedValue.equals(actualValue), - "Key child node with unexpected value, is: %s, should be: %s", actualValue, expectedValue); + for (final Entry key : getNodeIdentifier().getKeyValues().entrySet()) { + final DataContainerChild childNode = getChild(childrenQNamesToPaths.get(key.getKey())); + + // We have enough information to fill-in missing leaf nodes, so let's do that + if (childNode == null) { + LeafNode leaf = ImmutableNodes.leafNode(key.getKey(), key.getValue()); + LOG.debug("Adding leaf {} implied by key {}", leaf, key); + withChild(leaf); + } else { + DataValidationException.checkListKey(getNodeIdentifier(), key.getKey(), key.getValue(), + childNode.getValue()); + } } + + return new ImmutableMapEntryNode(getNodeIdentifier(), buildValue(), getAttributes()); } - static final class ImmutableMapEntryNode extends AbstractImmutableDataContainerAttrNode implements MapEntryNode { + private static final class ImmutableMapEntryNode + extends AbstractImmutableDataContainerAttrNode implements MapEntryNode { - ImmutableMapEntryNode(final InstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifier, - final Map> children, final Map attributes) { + ImmutableMapEntryNode(final NodeIdentifierWithPredicates nodeIdentifier, + final Map> children, + final Map attributes) { super(children, nodeIdentifier, attributes); } }