X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-adapter%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fadapter%2FCurrentAdapterSerializer.java;h=d6ff0c336f25aae9e3949264578391d23a6f803c;hb=cb0f3a767fa856c220edd674fda4d55dde408c64;hp=bad7ff3c3ecc91ad58ae1d28afec1c0833d56693;hpb=72ed8ba8aa471801ee06384a359de5aba59b6d05;p=mdsal.git diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/CurrentAdapterSerializer.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/CurrentAdapterSerializer.java index bad7ff3c3e..d6ff0c336f 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/CurrentAdapterSerializer.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/CurrentAdapterSerializer.java @@ -7,7 +7,7 @@ */ package org.opendaylight.mdsal.binding.dom.adapter; -import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; @@ -17,29 +17,36 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.ImmutableList; import java.lang.reflect.Method; import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.binding.api.ActionSpec; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.InstanceNotificationSpec; import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices; import org.opendaylight.mdsal.binding.dom.codec.spi.ForwardingBindingDOMCodecServices; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; -import org.opendaylight.yangtools.yang.binding.Action; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.model.api.ActionDefinition; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,11 +90,53 @@ public final class CurrentAdapterSerializer extends ForwardingBindingDOMCodecSer return subtrees.stream().map(this::toDOMDataTreeIdentifier).collect(Collectors.toSet()); } - @NonNull Absolute getActionPath(final @NonNull Class> type) { - // FIXME: we really just want a SchemaNodeIdentifier.Absolute here - final ActionDefinition schema = getRuntimeContext().getActionDefinition(type); - checkArgument(schema != null, "Failed to find schema for %s", type); - return Absolute.of(ImmutableList.copyOf(schema.getPath().getPathFromRoot())); + @NonNull Absolute getActionPath(final @NonNull ActionSpec spec) { + final var entry = resolvePath(spec.path()); + final var stack = entry.getKey(); + final var stmt = stack.enterSchemaTree(BindingReflections.findQName(spec.type()).bindTo(entry.getValue())); + verify(stmt instanceof ActionEffectiveStatement, "Action %s resolved to unexpected statement %s", spec, stmt); + return stack.toSchemaNodeIdentifier(); + } + + @NonNull Absolute getNotificationPath(final @NonNull InstanceNotificationSpec spec) { + final var entry = resolvePath(spec.path()); + final var stack = entry.getKey(); + final var stmt = stack.enterSchemaTree(BindingReflections.findQName(spec.type()).bindTo(entry.getValue())); + verify(stmt instanceof NotificationEffectiveStatement, "Notification %s resolved to unexpected statement %s", + spec, stmt); + return stack.toSchemaNodeIdentifier(); + } + + private @NonNull Entry resolvePath(final @NonNull InstanceIdentifier path) { + final var stack = SchemaInferenceStack.of(getRuntimeContext().getEffectiveModelContext()); + final var it = toYangInstanceIdentifier(path).getPathArguments().iterator(); + verify(it.hasNext(), "Unexpected empty instance identifier for %s", path); + + QNameModule lastNamespace; + do { + final var arg = it.next(); + if (arg instanceof AugmentationIdentifier) { + final var augChildren = ((AugmentationIdentifier) arg).getPossibleChildNames(); + verify(!augChildren.isEmpty(), "Invalid empty augmentation %s", arg); + lastNamespace = augChildren.iterator().next().getModule(); + continue; + } + + final var qname = arg.getNodeType(); + final var stmt = stack.enterDataTree(qname); + lastNamespace = qname.getModule(); + if (stmt instanceof ListEffectiveStatement) { + // Lists have two steps + verify(it.hasNext(), "Unexpected list termination at %s in %s", stmt, path); + // Verify just to make sure we are doing the right thing + final var skipped = it.next(); + verify(skipped instanceof NodeIdentifier, "Unexpected skipped list entry item %s in %s", skipped, path); + verify(stmt.argument().equals(skipped.getNodeType()), "Mismatched list entry item %s in %s", skipped, + path); + } + } while (it.hasNext()); + + return Map.entry(stack, lastNamespace); } // FIXME: This should be probably part of Binding Runtime context @@ -106,7 +155,7 @@ public final class CurrentAdapterSerializer extends ForwardingBindingDOMCodecSer } // FIXME: This should be probably part of Binding Runtime context - ImmutableBiMap getRpcMethodToSchemaPath(final Class key) { + ImmutableBiMap getRpcMethodToQName(final Class key) { final Module module = getModule(key); final ImmutableBiMap.Builder ret = ImmutableBiMap.builder(); try { @@ -123,7 +172,7 @@ public final class CurrentAdapterSerializer extends ForwardingBindingDOMCodecSer private Module getModule(final Class modeledClass) { final QNameModule moduleName = BindingReflections.getQNameModule(modeledClass); final BindingRuntimeContext localRuntimeContext = getRuntimeContext(); - final Module module = localRuntimeContext.getSchemaContext().findModule(moduleName).orElse(null); + final Module module = localRuntimeContext.getEffectiveModelContext().findModule(moduleName).orElse(null); if (module != null) { return module; } @@ -136,8 +185,8 @@ public final class CurrentAdapterSerializer extends ForwardingBindingDOMCodecSer private Method findRpcMethod(final Class key, final RpcDefinition rpcDef) throws NoSuchMethodException { - final String methodName = BindingMapping.getRpcMethodName(rpcDef.getQName()); - final Class inputClz = getRuntimeContext().getClassForSchema(rpcDef.getInput()); - return key.getMethod(methodName, inputClz); + final var rpcName = rpcDef.getQName(); + final var inputClz = getRuntimeContext().getRpcInput(rpcName); + return key.getMethod(BindingMapping.getRpcMethodName(rpcName), inputClz); } }