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%2FChoiceNodeCodecContext.java;h=6100d4db209e08b715689758243ce6da79fef5f3;hb=11408d627adca7eb71ac956c3ad01f75b6b91596;hp=6d0a3ba1d960c56134ad6230065d98a845aa6397;hpb=ae4b15bb715dd7206b793629ef668eedec2403f9;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceNodeCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceNodeCodecContext.java index 6d0a3ba1d9..6100d4db20 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceNodeCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceNodeCodecContext.java @@ -18,6 +18,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.MultimapBuilder.SetMultimapBuilder; import com.google.common.collect.Multimaps; import com.google.common.collect.SetMultimap; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; @@ -28,7 +29,12 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.binding.model.api.JavaTypeName; +import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType; +import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType; import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; @@ -36,12 +42,11 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils; import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode; +import org.opendaylight.yangtools.yang.data.util.NormalizedNodeSchemaUtils; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; -import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,7 +97,7 @@ import org.slf4j.LoggerFactory; * ambiguous reference and issue warn once when they are encountered -- tracking warning information in * {@link #ambiguousByCaseChildWarnings}. */ -final class ChoiceNodeCodecContext extends DataContainerCodecContext { +final class ChoiceNodeCodecContext extends DataContainerCodecContext { private static final Logger LOG = LoggerFactory.getLogger(ChoiceNodeCodecContext.class); private final ImmutableMap> byYangCaseChild; @@ -101,7 +106,7 @@ final class ChoiceNodeCodecContext extends DataContainerCo private final ImmutableMap, DataContainerCodecPrototype> byClass; private final Set> ambiguousByCaseChildWarnings; - ChoiceNodeCodecContext(final DataContainerCodecPrototype prototype) { + ChoiceNodeCodecContext(final DataContainerCodecPrototype prototype) { super(prototype); final Map> byYangCaseChildBuilder = new HashMap<>(); @@ -110,10 +115,11 @@ final class ChoiceNodeCodecContext extends DataContainerCo SetMultimapBuilder.hashKeys().hashSetValues().build(); final Set> potentialSubstitutions = new HashSet<>(); // Walks all cases for supplied choice in current runtime context - for (final Class caze : factory().getRuntimeContext().getCases(getBindingClass())) { + // FIXME: 9.0.0: factory short-circuits to prototype, just as getBindingClass() does + for (final Class caze : loadCaseClasses()) { // We try to load case using exact match thus name // and original schema must equals - final DataContainerCodecPrototype cazeDef = loadCase(caze); + final DataContainerCodecPrototype cazeDef = loadCase(caze); // If we have case definition, this case is instantiated // at current location and thus is valid in context of parent choice if (cazeDef != null) { @@ -125,17 +131,21 @@ final class ChoiceNodeCodecContext extends DataContainerCo childToCase.put(cazeChild, cazeDef); } // Updates collection of YANG instance identifier to case - for (final DataSchemaNode cazeChild : cazeDef.getSchema().getChildNodes()) { - if (cazeChild.isAugmenting()) { - final AugmentationSchemaNode augment = SchemaUtils.findCorrespondingAugment(cazeDef.getSchema(), - cazeChild); - if (augment != null) { - byYangCaseChildBuilder.put(DataSchemaContextNode.augmentationIdentifierFrom(augment), - cazeDef); - continue; + for (var stmt : cazeDef.getType().statement().effectiveSubstatements()) { + if (stmt instanceof DataSchemaNode) { + final DataSchemaNode cazeChild = (DataSchemaNode) stmt; + if (cazeChild.isAugmenting()) { + final AugmentationSchemaNode augment = NormalizedNodeSchemaUtils.findCorrespondingAugment( + // FIXME: bad cast + (DataSchemaNode) cazeDef.getType().statement(), cazeChild); + if (augment != null) { + byYangCaseChildBuilder.put(DataSchemaContextNode.augmentationIdentifierFrom(augment), + cazeDef); + continue; + } } + byYangCaseChildBuilder.put(NodeIdentifier.create(cazeChild.getQName()), cazeDef); } - byYangCaseChildBuilder.put(NodeIdentifier.create(cazeChild.getQName()), cazeDef); } } else { /* @@ -189,6 +199,28 @@ final class ChoiceNodeCodecContext extends DataContainerCo byClass = ImmutableMap.copyOf(byClassBuilder); } + private List> loadCaseClasses() { + final var context = factory().getRuntimeContext(); + final var type = getType(); + + return Stream.concat(type.validCaseChildren().stream(), type.additionalCaseChildren().stream()) + .map(caseChild -> { + final var caseName = caseChild.getIdentifier(); + try { + return context.loadClass(caseName); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Failed to load class for " + caseName, e); + } + }) + .collect(Collectors.toUnmodifiableList()); + } + + @Override + public WithStatus getSchema() { + // FIXME: Bad cast, we should be returning an EffectiveStatement perhaps? + return (WithStatus) getType().statement(); + } + @SuppressWarnings("unchecked") @Override public DataContainerCodecContext streamChild(final Class childClass) { @@ -212,15 +244,14 @@ final class ChoiceNodeCodecContext extends DataContainerCo return Iterables.concat(byCaseChildClass.keySet(), ambiguousByCaseChildClass.keySet()); } - protected DataContainerCodecPrototype loadCase(final Class childClass) { - final Optional childSchema = factory().getRuntimeContext().getCaseSchemaDefinition(getSchema(), - childClass); - if (childSchema.isPresent()) { - return DataContainerCodecPrototype.from(childClass, childSchema.get(), factory()); + protected DataContainerCodecPrototype loadCase(final Class childClass) { + final var child = getType().bindingCaseChild(JavaTypeName.create(childClass)); + if (child == null) { + LOG.debug("Supplied class {} is not valid case in schema {}", childClass, getSchema()); + return null; } - LOG.debug("Supplied class {} is not valid case in schema {}", childClass, getSchema()); - return null; + return DataContainerCodecPrototype.from(childClass, child, factory()); } @Override @@ -236,12 +267,13 @@ final class ChoiceNodeCodecContext extends DataContainerCo .yangPathArgumentChild(arg); } - @SuppressWarnings("unchecked") @Override - public D deserialize(final NormalizedNode data) { + @SuppressWarnings("unchecked") + @SuppressFBWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "See FIXME below") + public D deserialize(final NormalizedNode data) { checkArgument(data instanceof ChoiceNode); final ChoiceNode casted = (ChoiceNode) data; - final NormalizedNode first = Iterables.getFirst(casted.getValue(), null); + final NormalizedNode first = Iterables.getFirst(casted.body(), null); if (first == null) { // FIXME: this needs to be sorted out @@ -252,7 +284,7 @@ final class ChoiceNodeCodecContext extends DataContainerCo } @Override - protected Object deserializeObject(final NormalizedNode normalizedNode) { + protected Object deserializeObject(final NormalizedNode normalizedNode) { return deserialize(normalizedNode); }