X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fcodec%2Fimpl%2FChoiceCodecContext.java;h=6fcecaafb50d8bbf77ded8d923105b2404dd8ddc;hb=0032cbc207750ee84b76dfc395c29ade7adc76d4;hp=a7ec5fabb26744a05b1317d33d9097cc606f1e20;hpb=74ef67db283874e6024413355267120c77a6095c;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceCodecContext.java index a7ec5fabb2..6fcecaafb5 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceCodecContext.java @@ -9,7 +9,6 @@ package org.opendaylight.mdsal.binding.dom.codec.impl; import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -17,29 +16,27 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.MultimapBuilder.SetMultimapBuilder; import com.google.common.collect.Multimaps; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; +import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode; -import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingChoiceCodecTreeNode; import org.opendaylight.mdsal.binding.model.api.JavaTypeName; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType; import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType; -import org.opendaylight.yangtools.yang.binding.BindingObject; +import org.opendaylight.yangtools.yang.binding.ChoiceIn; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.binding.DataObjectStep; import org.opendaylight.yangtools.yang.binding.contract.Naming; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; @@ -94,8 +91,9 @@ import org.slf4j.LoggerFactory; * ambiguous reference and issue warn once when they are encountered -- tracking warning information in * {@link #ambiguousByCaseChildWarnings}. */ -final class ChoiceCodecContext extends CommonDataObjectCodecContext - implements BindingDataObjectCodecTreeNode { +final class ChoiceCodecContext> + extends DataContainerCodecContext> + implements BindingChoiceCodecTreeNode { private static final Logger LOG = LoggerFactory.getLogger(ChoiceCodecContext.class); private final ImmutableListMultimap, CommonDataObjectCodecPrototype> ambiguousByCaseChildClass; @@ -104,11 +102,12 @@ final class ChoiceCodecContext extends CommonDataObjectCod private final ImmutableMap, CommonDataObjectCodecPrototype> byClass; private final Set> ambiguousByCaseChildWarnings; - ChoiceCodecContext(final Class cls, final ChoiceRuntimeType type, final CodecContextFactory factory) { - this(new ChoiceCodecPrototype(Item.of(cls), type, factory)); + ChoiceCodecContext(final Class javaClass, final ChoiceRuntimeType runtimeType, + final CodecContextFactory contextFactory) { + this(new ChoiceCodecPrototype<>(contextFactory, runtimeType, javaClass)); } - ChoiceCodecContext(final ChoiceCodecPrototype prototype) { + ChoiceCodecContext(final ChoiceCodecPrototype prototype) { super(prototype); final var byYangCaseChildBuilder = new HashMap(); final var byClassBuilder = new HashMap, CommonDataObjectCodecPrototype>(); @@ -116,8 +115,8 @@ final class ChoiceCodecContext extends CommonDataObjectCod ., CommonDataObjectCodecPrototype>build(); // Load case statements valid in this choice and keep track of their names - final var choiceType = prototype.getType(); - final var factory = prototype.getFactory(); + final var choiceType = prototype.runtimeType(); + final var factory = prototype.contextFactory(); final var localCases = new HashSet(); for (var caseType : choiceType.validCaseChildren()) { @SuppressWarnings("unchecked") @@ -148,7 +147,7 @@ final class ChoiceCodecContext extends CommonDataObjectCod if (cases.size() != 1) { // Sort all possibilities by their FQCN to retain semi-predictable results final var list = new ArrayList<>(entry.getValue()); - list.sort(Comparator.comparing(proto -> proto.getBindingClass().getCanonicalName())); + list.sort(Comparator.comparing(proto -> proto.javaClass().getCanonicalName())); ambiguousByCaseBuilder.putAll(entry.getKey(), list); } else { unambiguousByCaseBuilder.put(entry.getKey(), cases.iterator().next()); @@ -204,7 +203,7 @@ final class ChoiceCodecContext extends CommonDataObjectCod @Override public WithStatus getSchema() { // FIXME: Bad cast, we should be returning an EffectiveStatement perhaps? - return (WithStatus) type().statement(); + return (WithStatus) prototype().runtimeType().statement(); } @Override @@ -217,59 +216,42 @@ final class ChoiceCodecContext extends CommonDataObjectCod } @Override - public CodecContext yangPathArgumentChild(final YangInstanceIdentifier.PathArgument arg) { + public CodecContext yangPathArgumentChild(final PathArgument arg) { return ((CaseCodecContext) super.yangPathArgumentChild(arg)).yangPathArgumentChild(arg); } @Override - CaseCodecPrototype yangChildSupplier(final NodeIdentifier arg) { + CodecContextSupplier yangChildSupplier(final NodeIdentifier arg) { return byYangCaseChild.get(arg); } @Override - @SuppressWarnings("unchecked") - @SuppressFBWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "See FIXME below") - public D deserialize(final NormalizedNode data) { - final var casted = checkDataArgument(ChoiceNode.class, data); - final var first = Iterables.getFirst(casted.body(), null); - - if (first == null) { - // FIXME: this needs to be sorted out + T deserializeObject(final NormalizedNode normalizedNode) { + final var casted = checkDataArgument(ChoiceNode.class, normalizedNode); + final var it = casted.body().iterator(); + if (!it.hasNext()) { + // FIXME: can this reasonably happen? Empty choice nodes do not have semantics, or do they? return null; } - final var caze = byYangCaseChild.get(first.name()); - return ((CaseCodecContext) caze.getCodecContext()).deserialize(data); - } - @Override - public NormalizedNode serialize(final D data) { - return serializeImpl(data); - } - - @Override - protected Object deserializeObject(final NormalizedNode normalizedNode) { - return deserialize(normalizedNode); - } - - @Override - public PathArgument deserializePathArgument(final YangInstanceIdentifier.PathArgument arg) { - checkArgument(getDomPathArgument().equals(arg)); - return null; - } - - @Override - public YangInstanceIdentifier.PathArgument serializePathArgument(final PathArgument arg) { - // FIXME: check for null, since binding container is null. - return getDomPathArgument(); + final var childName = it.next().name(); + final var caze = childNonNull(byYangCaseChild.get(childName), childName, "%s is not a valid case child of %s", + childName, this); + return (T) caze.getCodecContext().deserializeObject(casted); } @Override - public BindingNormalizedNodeCachingCodec createCachingCodec( - final ImmutableCollection> cacheSpecifier) { - return createCachingCodec(this, cacheSpecifier); + public CommonDataObjectCodecContext bindingPathArgumentChild(final DataObjectStep step, + final List builder) { + final var caseType = step.caseType(); + // Prefer non-ambiguous addressing, which should not pose any problems. Otherwise fall back to checking for + // ambiguities + final var caze = caseType != null ? getStreamChild(caseType) : getCaseByChildClass(step.type()); + caze.addYangPathArgument(step, builder); + return caze.bindingPathArgumentChild(step, builder); } - DataContainerCodecContext getCaseByChildClass(final @NonNull Class type) { + private DataContainerCodecContext getCaseByChildClass(final @NonNull Class type) { var result = byCaseChildClass.get(type); if (result == null) { // We have not found an unambiguous result, try ambiguous ones @@ -282,13 +264,13 @@ final class ChoiceCodecContext extends CommonDataObjectCod Ambiguous reference {} to child of {} resolved to {}, the first case in {} This mapping is \ not guaranteed to be stable and is subject to variations based on runtime circumstances. \ Please see the stack trace for hints about the source of ambiguity.""", - type, bindingArg(), result.getBindingClass(), - Lists.transform(inexact, CommonDataObjectCodecPrototype::getBindingClass), new Throwable()); + type, getBindingClass(), result.javaClass(), + Lists.transform(inexact, CommonDataObjectCodecPrototype::javaClass), new Throwable()); } } } - return childNonNull(result, type, "Class %s is not child of any cases for %s", type, bindingArg()) + return childNonNull(result, type, "Class %s is not child of any cases for %s", type, getBindingClass()) .getCodecContext(); }