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=8454de4f25a283c49e07ded78f501b23ad5e5429;hb=f3be50ed801e5de305eb46b824e6bc3c6075e4bc;hp=fb20296e4a14843af58da00d01c77366c1e422d9;hpb=258e272a3de877caddeebc9940eb34b4b303cecb;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 fb20296e4a..8454de4f25 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,25 +16,23 @@ 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.contract.Naming; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -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 @@ -222,54 +221,43 @@ final class ChoiceCodecContext extends CommonDataObjectCod } @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 + protected 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.get()).deserialize(data); - } - @Override - public NormalizedNode serialize(final D data) { - return serializeImpl(data); - } - - @Override - protected Object deserializeObject(final NormalizedNode normalizedNode) { - return deserialize(normalizedNode); + 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 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(); - } + public CommonDataObjectCodecContext bindingPathArgumentChild(final PathArgument arg, + final List builder) { + final var caseType = arg.getCaseType(); + final var type = arg.getType(); + final DataContainerCodecContext caze; + if (caseType.isPresent()) { + // Non-ambiguous addressing this should not pose any problems + caze = getStreamChild(caseType.orElseThrow()); + } else { + caze = getCaseByChildClass(type); + } - @Override - public BindingNormalizedNodeCachingCodec createCachingCodec( - final ImmutableCollection> cacheSpecifier) { - return createCachingCodec(this, cacheSpecifier); + caze.addYangPathArgument(arg, builder); + return caze.bindingPathArgumentChild(arg, 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 +270,14 @@ 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()).get(); + return childNonNull(result, type, "Class %s is not child of any cases for %s", type, getBindingClass()) + .getCodecContext(); } /** @@ -305,7 +294,7 @@ final class ChoiceCodecContext extends CommonDataObjectCod checkArgument(DataContainer.class.isAssignableFrom(type), "Supplied type must be derived from DataContainer"); final var ret = new LinkedList>(); for (var method : type.getMethods()) { - AbstractDataContainerAnalysis.getYangModeledReturnType(method, Naming.GETTER_PREFIX) + DataContainerAnalysis.getYangModeledReturnType(method, Naming.GETTER_PREFIX) .ifPresent(entity -> ret.add((Class) entity)); } return ret;