X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fbinding%2Fdata%2Fcodec%2Fimpl%2FDataContainerCodecPrototype.java;fp=binding%2Fmdsal-binding-dom-codec%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fbinding%2Fdata%2Fcodec%2Fimpl%2FDataContainerCodecPrototype.java;h=88b5cd984d538a169d70f69b6e3b4b18ce642457;hb=076dcd04523bd003935796c3795ea4f81dfa8898;hp=4560bd6274822ce1a3d6c1db3819c7a2eff40940;hpb=dcd3e44d3c582bd12287e56798e12478fcdbc96d;p=mdsal.git diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/DataContainerCodecPrototype.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/DataContainerCodecPrototype.java index 4560bd6274..88b5cd984d 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/DataContainerCodecPrototype.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/DataContainerCodecPrototype.java @@ -9,6 +9,7 @@ package org.opendaylight.yangtools.binding.data.codec.impl; import com.google.common.collect.Iterables; import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode.ChildAddressabilitySummary; import org.opendaylight.yangtools.binding.data.codec.impl.NodeCodecContext.CodecContextFactory; import org.opendaylight.yangtools.yang.binding.DataRoot; import org.opendaylight.yangtools.yang.binding.Identifiable; @@ -18,16 +19,23 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.TypedSchemaNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; final class DataContainerCodecPrototype implements NodeContextSupplier { + private static final Logger LOG = LoggerFactory.getLogger(DataContainerCodecPrototype.class); private final T schema; private final QNameModule namespace; @@ -35,7 +43,9 @@ final class DataContainerCodecPrototype implements NodeContextSupplier { private final Class bindingClass; private final InstanceIdentifier.Item bindingArg; private final YangInstanceIdentifier.PathArgument yangArg; - private volatile DataContainerCodecContext instance = null; + private final ChildAddressabilitySummary childAddressabilitySummary; + + private volatile DataContainerCodecContext instance = null; @SuppressWarnings({"rawtypes", "unchecked"}) private DataContainerCodecPrototype(final Class cls, final YangInstanceIdentifier.PathArgument arg, final T nodeSchema, @@ -52,6 +62,81 @@ final class DataContainerCodecPrototype implements NodeContextSupplier { } else { this.namespace = arg.getNodeType().getModule(); } + + this.childAddressabilitySummary = computeChildAddressabilitySummary(nodeSchema); + } + + private static ChildAddressabilitySummary computeChildAddressabilitySummary(final Object nodeSchema) { + if (nodeSchema instanceof DataNodeContainer) { + boolean haveAddressable = false; + boolean haveUnaddressable = false; + for (DataSchemaNode child : ((DataNodeContainer) nodeSchema).getChildNodes()) { + if (child instanceof ContainerSchemaNode || child instanceof AugmentationSchema) { + haveAddressable = true; + } else if (child instanceof ListSchemaNode) { + if (((ListSchemaNode) child).getKeyDefinition().isEmpty()) { + haveUnaddressable = true; + } else { + haveAddressable = true; + } + } else if (child instanceof AnyDataSchemaNode || child instanceof AnyXmlSchemaNode + || child instanceof TypedSchemaNode) { + haveUnaddressable = true; + } else if (child instanceof ChoiceSchemaNode) { + switch (computeChildAddressabilitySummary(child)) { + case ADDRESSABLE: + haveAddressable = true; + break; + case MIXED: + haveAddressable = true; + haveUnaddressable = true; + break; + case UNADDRESSABLE: + haveUnaddressable = true; + break; + default: + throw new IllegalStateException("Unhandled accessibility summary for " + child); + } + } else { + LOG.warn("Unhandled child node {}", child); + } + } + + if (!haveAddressable) { + // Empty or all are unaddressable + return ChildAddressabilitySummary.UNADDRESSABLE; + } + + return haveUnaddressable ? ChildAddressabilitySummary.MIXED : ChildAddressabilitySummary.ADDRESSABLE; + } else if (nodeSchema instanceof ChoiceSchemaNode) { + boolean haveAddressable = false; + boolean haveUnaddressable = false; + for (ChoiceCaseNode child : ((ChoiceSchemaNode) nodeSchema).getCases()) { + switch (computeChildAddressabilitySummary(child)) { + case ADDRESSABLE: + haveAddressable = true; + break; + case UNADDRESSABLE: + haveUnaddressable = true; + break; + case MIXED: + // A child is mixed, which means we are mixed, too + return ChildAddressabilitySummary.MIXED; + default: + throw new IllegalStateException("Unhandled accessibility summary for " + child); + } + } + + if (!haveAddressable) { + // Empty or all are unaddressable + return ChildAddressabilitySummary.UNADDRESSABLE; + } + + return haveUnaddressable ? ChildAddressabilitySummary.MIXED : ChildAddressabilitySummary.ADDRESSABLE; + } + + // No child nodes possible: return unaddressable + return ChildAddressabilitySummary.UNADDRESSABLE; } @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -63,7 +148,7 @@ final class DataContainerCodecPrototype implements NodeContextSupplier { static DataContainerCodecPrototype rootPrototype(final CodecContextFactory factory) { final SchemaContext schema = factory.getRuntimeContext().getSchemaContext(); final NodeIdentifier arg = NodeIdentifier.create(schema.getQName()); - return new DataContainerCodecPrototype(DataRoot.class, arg, schema, factory); + return new DataContainerCodecPrototype<>(DataRoot.class, arg, schema, factory); } @@ -75,13 +160,17 @@ final class DataContainerCodecPrototype implements NodeContextSupplier { static DataContainerCodecPrototype from(final Class augClass, final NotificationDefinition schema, final CodecContextFactory factory) { final PathArgument arg = NodeIdentifier.create(schema.getQName()); - return new DataContainerCodecPrototype(augClass,arg, schema, factory); + return new DataContainerCodecPrototype<>(augClass,arg, schema, factory); } protected T getSchema() { return schema; } + ChildAddressabilitySummary getChildAddressabilitySummary() { + return childAddressabilitySummary; + } + protected QNameModule getNamespace() { return namespace; }