From c43197e66be08a0ffaa00bbe8405fa4ba23b8656 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 23 Nov 2018 00:43:32 +0100 Subject: [PATCH] Refactor ImmutableMapEntryNodeSchemaAwareBuilder This builder's logic is not entirely efficient, as it can constructs unnecessary NodeIdentifierWithPredicates purely for checking purposes. Furthermore we can side-step child validation when we are switching by available children, as we have the entryset available. JIRA: YANGTOOLS-917 Change-Id: I57d0a156ced3abce7e61403c2b390c074850d612 Signed-off-by: Robert Varga --- ...mutableMapEntryNodeSchemaAwareBuilder.java | 59 +++++++++++++------ .../impl/valid/DataValidationException.java | 14 +++-- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeSchemaAwareBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeSchemaAwareBuilder.java index f5165cea60..b68d7621b5 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeSchemaAwareBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapEntryNodeSchemaAwareBuilder.java @@ -7,17 +7,21 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl; -import com.google.common.base.Preconditions; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableMap; import java.util.Collection; -import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; +import org.opendaylight.yangtools.util.ImmutableMapTemplate; import org.opendaylight.yangtools.yang.common.QName; 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.MapEntryNode; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataNodeContainerValidator; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException.IllegalListKeyException; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; public final class ImmutableMapEntryNodeSchemaAwareBuilder extends ImmutableMapEntryNodeBuilder { @@ -26,7 +30,7 @@ public final class ImmutableMapEntryNodeSchemaAwareBuilder extends ImmutableMapE private final DataNodeContainerValidator validator; ImmutableMapEntryNodeSchemaAwareBuilder(final ListSchemaNode schema) { - this.schema = Preconditions.checkNotNull(schema); + this.schema = requireNonNull(schema); this.validator = new DataNodeContainerValidator(schema); } @@ -48,29 +52,50 @@ public final class ImmutableMapEntryNodeSchemaAwareBuilder extends ImmutableMapE return super.build(); } + public static DataContainerNodeAttrBuilder create( + final ListSchemaNode schema) { + return new ImmutableMapEntryNodeSchemaAwareBuilder(schema); + } + /** * Build map entry node identifier from schema and provided children. */ private NodeIdentifierWithPredicates constructNodeIdentifier() { - Collection keys = schema.getKeyDefinition(); + final Map predicates; + final Collection keys = schema.getKeyDefinition(); + if (!keys.isEmpty()) { + predicates = keyDefToPredicates(keys); + } else if (!childrenQNamesToPaths.isEmpty()) { + predicates = childrenToPredicates(); + } else { + predicates = ImmutableMap.of(); + } + return new NodeIdentifierWithPredicates(schema.getQName(), predicates); + } - if (keys.isEmpty()) { - keys = childrenQNamesToPaths.keySet(); + private Map childrenToPredicates() { + final Object[] values = new Object[childrenQNamesToPaths.size()]; + int offset = 0; + for (Entry entry : childrenQNamesToPaths.entrySet()) { + values[offset++] = nonnullKeyValue(entry.getKey(), getChild(entry.getValue())).getValue(); } + return ImmutableMapTemplate.ordered(childrenQNamesToPaths.keySet()).instantiateWithValues(values); + } - final Map keysToValues = new LinkedHashMap<>(); + private Map keyDefToPredicates(final Collection keys) { + final Object[] values = new Object[keys.size()]; + int offset = 0; for (QName key : keys) { - final DataContainerChild valueForKey = getChild(childrenQNamesToPaths.get(key)); - DataValidationException.checkListKey(valueForKey, key, new NodeIdentifierWithPredicates( - schema.getQName(), keysToValues)); - keysToValues.put(key, valueForKey.getValue()); + values[offset++] = nonnullKeyValue(key, getChild(childrenQNamesToPaths.get(key))).getValue(); } - - return new NodeIdentifierWithPredicates(schema.getQName(), keysToValues); + return ImmutableMapTemplate.ordered(keys).instantiateWithValues(values); } - public static DataContainerNodeAttrBuilder create( - final ListSchemaNode schema) { - return new ImmutableMapEntryNodeSchemaAwareBuilder(schema); + private DataContainerChild nonnullKeyValue(final QName key, final DataContainerChild value) { + if (value != null) { + return value; + } + throw new IllegalListKeyException("Key value not present for key: %s, in: %s values %s", key, schema.getQName(), + buildValue()); } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/valid/DataValidationException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/valid/DataValidationException.java index e79cefb616..0b3a7f4fc5 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/valid/DataValidationException.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/valid/DataValidationException.java @@ -7,6 +7,7 @@ */ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid; +import com.google.common.annotations.Beta; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -98,17 +99,22 @@ public class DataValidationException extends RuntimeException { } } - private static final class IllegalListKeyException extends DataValidationException { + @Beta + public static final class IllegalListKeyException extends DataValidationException { private static final long serialVersionUID = 1L; + public IllegalListKeyException(final String format, final Object... args) { + super(String.format(format, args)); + } + IllegalListKeyException(final QName keyQName, final NodeIdentifierWithPredicates id) { - super(String.format("Key value not present for key: %s, in: %s", keyQName, id)); + this("Key value not present for key: %s, in: %s", keyQName, id); } IllegalListKeyException(final QName keyQName, final NodeIdentifierWithPredicates id, final Object actualValue, final Object expectedValue) { - super(String.format("Illegal value for key: %s, in: %s, actual value: %s, expected value from key: %s", - keyQName, id, actualValue, expectedValue)); + this("Illegal value for key: %s, in: %s, actual value: %s, expected value from key: %s", + keyQName, id, actualValue, expectedValue); } } } -- 2.36.6