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%2FBindingToNormalizedNodeCodec.java;h=55fde2cd655b19b5e47517d3ca0ec7895f84cf50;hb=6e6ebc43866204667658f8bbf7cfb6233caffdc7;hp=646c026d8ef71c786ecffeed80523c6eb1b9dd7c;hpb=3e577f99de723d2e6dce97d95d1cd0a19f097fe4;p=mdsal.git diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java index 646c026d8e..55fde2cd65 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java @@ -7,48 +7,66 @@ */ package org.opendaylight.mdsal.binding.dom.adapter; -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; + 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.ImmutableSet; +import com.google.common.collect.Iterators; import java.lang.reflect.Method; -import java.net.URI; +import java.time.Instant; import java.util.AbstractMap.SimpleEntry; import java.util.Collection; -import java.util.Date; import java.util.HashSet; -import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry; +import org.opendaylight.mdsal.binding.dom.codec.impl.MissingSchemaException; +import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy; +import org.opendaylight.mdsal.binding.generator.util.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.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.yangtools.binding.data.codec.impl.MissingSchemaException; -import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; -import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext; -import org.opendaylight.yangtools.yang.binding.BindingMapping; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.Action; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.binding.RpcInput; +import org.opendaylight.yangtools.yang.binding.RpcOutput; import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.binding.util.BindingReflections; import org.opendaylight.yangtools.yang.common.QNameModule; 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.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.model.api.ActionDefinition; +import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; @@ -59,46 +77,60 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, +/** + * A combinations of {@link BindingCodecTreeFactory} and {@link BindingNormalizedNodeSerializer}, with internal + * caching of instance identifiers. + * + *

+ * NOTE: this class is non-final to allow controller adapter migration without duplicated code. + */ +@Singleton +public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, BindingNormalizedNodeSerializer, SchemaContextListener, AutoCloseable { private static final long WAIT_DURATION_SEC = 5; private static final Logger LOG = LoggerFactory.getLogger(BindingToNormalizedNodeCodec.class); - private final BindingNormalizedNodeCodecRegistry codecRegistry; - - private final GeneratedClassLoadingStrategy classLoadingStrategy; - private final FutureSchema futureSchema; private final LoadingCache, YangInstanceIdentifier> iiCache = CacheBuilder.newBuilder() .softValues().build(new CacheLoader, YangInstanceIdentifier>() { - @Override - public YangInstanceIdentifier load(final InstanceIdentifier key) throws Exception { + public YangInstanceIdentifier load(final InstanceIdentifier key) { return toYangInstanceIdentifierBlocking(key); } - }); + private final BindingNormalizedNodeCodecRegistry codecRegistry; + private final ClassLoadingStrategy classLoadingStrategy; + private final FutureSchema futureSchema; + private ListenerRegistration listenerRegistration; - private volatile BindingRuntimeContext runtimeContext; - - public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, + @Inject + public BindingToNormalizedNodeCodec(final ClassLoadingStrategy classLoadingStrategy, final BindingNormalizedNodeCodecRegistry codecRegistry) { - this(classLoadingStrategy,codecRegistry,false); + this(classLoadingStrategy, codecRegistry, false); + } + public BindingToNormalizedNodeCodec(final ClassLoadingStrategy classLoadingStrategy, + final BindingNormalizedNodeCodecRegistry codecRegistry, final boolean waitForSchema) { + this.classLoadingStrategy = requireNonNull(classLoadingStrategy, "classLoadingStrategy"); + this.codecRegistry = requireNonNull(codecRegistry, "codecRegistry"); + this.futureSchema = FutureSchema.create(WAIT_DURATION_SEC, TimeUnit.SECONDS, waitForSchema); } - public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, - final BindingNormalizedNodeCodecRegistry codecRegistry,final boolean waitForSchema) { - this.classLoadingStrategy = Preconditions.checkNotNull(classLoadingStrategy,"classLoadingStrategy"); - this.codecRegistry = Preconditions.checkNotNull(codecRegistry,"codecRegistry"); - this.futureSchema = waitForSchema ? new FutureSchema(WAIT_DURATION_SEC, TimeUnit.SECONDS) : null; + public static BindingToNormalizedNodeCodec newInstance(final ClassLoadingStrategy classLoadingStrategy, + final DOMSchemaService schemaService) { + final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(); + BindingToNormalizedNodeCodec instance = new BindingToNormalizedNodeCodec( + classLoadingStrategy, codecRegistry, true); + instance.listenerRegistration = schemaService.registerSchemaContextListener(instance); + return instance; } - YangInstanceIdentifier toYangInstanceIdentifierBlocking(final InstanceIdentifier binding) { + protected YangInstanceIdentifier toYangInstanceIdentifierBlocking( + final InstanceIdentifier binding) { try { return codecRegistry.toYangInstanceIdentifier(binding); } catch (final MissingSchemaException e) { - waitForSchema(decompose(binding),e); + waitForSchema(decompose(binding), e); return codecRegistry.toYangInstanceIdentifier(binding); } } @@ -113,22 +145,21 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto * @throws IllegalArgumentException * If supplied Instance Identifier is not valid. */ - public YangInstanceIdentifier toNormalized(final InstanceIdentifier binding) { + public final YangInstanceIdentifier toNormalized(final InstanceIdentifier binding) { return codecRegistry.toYangInstanceIdentifier(binding); } @Override - public YangInstanceIdentifier toYangInstanceIdentifier(final InstanceIdentifier binding) { + public final YangInstanceIdentifier toYangInstanceIdentifier(final InstanceIdentifier binding) { return codecRegistry.toYangInstanceIdentifier(binding); } - - YangInstanceIdentifier toYangInstanceIdentifierCached(final InstanceIdentifier binding) { - return iiCache .getUnchecked(binding); + protected YangInstanceIdentifier toYangInstanceIdentifierCached(final InstanceIdentifier binding) { + return iiCache.getUnchecked(binding); } @Override - public Entry> toNormalizedNode( + public final Entry> toNormalizedNode( final InstanceIdentifier path, final T data) { try { return codecRegistry.toNormalizedNode(path, data); @@ -149,63 +180,103 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto * as value. */ @SuppressWarnings({"unchecked", "rawtypes"}) - public Entry> toNormalizedNode( + public final Entry> toNormalizedNode( final Entry, DataObject> binding) { - return toNormalizedNode((InstanceIdentifier) binding.getKey(),binding.getValue()); + return toNormalizedNode((InstanceIdentifier) binding.getKey(), binding.getValue()); } @Override - public Entry, DataObject> fromNormalizedNode(final YangInstanceIdentifier path, + public final Entry, DataObject> fromNormalizedNode(final YangInstanceIdentifier path, final NormalizedNode data) { return codecRegistry.fromNormalizedNode(path, data); } @Override - public Notification fromNormalizedNodeNotification(final SchemaPath path, final ContainerNode data) { + public final Notification fromNormalizedNodeNotification(final SchemaPath path, final ContainerNode data) { return codecRegistry.fromNormalizedNodeNotification(path, data); } @Override - public DataObject fromNormalizedNodeRpcData(final SchemaPath path, final ContainerNode data) { + public final Notification fromNormalizedNodeNotification(final SchemaPath path, final ContainerNode data, + final Instant eventInstant) { + return codecRegistry.fromNormalizedNodeNotification(path, data, eventInstant); + } + + @Override + public final DataObject fromNormalizedNodeRpcData(final SchemaPath path, final ContainerNode data) { return codecRegistry.fromNormalizedNodeRpcData(path, data); } @Override - public InstanceIdentifier fromYangInstanceIdentifier(final YangInstanceIdentifier dom) { + public T fromNormalizedNodeActionInput(final Class> action, + final ContainerNode input) { + return codecRegistry.fromNormalizedNodeActionInput(action, input); + } + + @Override + public T fromNormalizedNodeActionOutput(final Class> action, + final ContainerNode output) { + return codecRegistry.fromNormalizedNodeActionOutput(action, output); + } + + @Override + public final InstanceIdentifier fromYangInstanceIdentifier(final YangInstanceIdentifier dom) { return codecRegistry.fromYangInstanceIdentifier(dom); } @Override - public ContainerNode toNormalizedNodeNotification(final Notification data) { + public final ContainerNode toNormalizedNodeNotification(final Notification data) { return codecRegistry.toNormalizedNodeNotification(data); } @Override - public ContainerNode toNormalizedNodeRpcData(final DataContainer data) { + public final ContainerNode toNormalizedNodeRpcData(final DataContainer data) { return codecRegistry.toNormalizedNodeRpcData(data); } + @Override + public ContainerNode toNormalizedNodeActionInput(final Class> action, + final RpcInput input) { + return codecRegistry.toNormalizedNodeActionInput(action, input); + } + + @Override + public ContainerNode toNormalizedNodeActionOutput(final Class> action, + final RpcOutput output) { + return codecRegistry.toNormalizedNodeActionOutput(action, output); + } + + @Override + public BindingLazyContainerNode toLazyNormalizedNodeActionInput( + final Class> action, final NodeIdentifier identifier, final RpcInput input) { + return codecRegistry.toLazyNormalizedNodeActionInput(action, identifier, input); + } + + @Override + public BindingLazyContainerNode toLazyNormalizedNodeActionOutput( + final Class> action, final NodeIdentifier identifier, final RpcOutput output) { + return codecRegistry.toLazyNormalizedNodeActionOutput(action, identifier, output); + } + /** * Returns a Binding-Aware instance identifier from normalized * instance-identifier if it is possible to create representation. * *

- * Returns Optional.absent for cases where target is mixin node except + * Returns Optional.empty for cases where target is mixin node except * augmentation. - * */ - public Optional> toBinding(final YangInstanceIdentifier normalized) + public final Optional> toBinding(final YangInstanceIdentifier normalized) throws DeserializationException { try { - return Optional.>fromNullable( - codecRegistry.fromYangInstanceIdentifier(normalized)); + return Optional.ofNullable(codecRegistry.fromYangInstanceIdentifier(normalized)); } catch (final IllegalArgumentException e) { - return Optional.absent(); + return Optional.empty(); } } - public Optional, DataObject>> toBinding( - @Nonnull final Entry> normalized) + public final Optional, DataObject>> toBinding( + final @NonNull Entry> normalized) throws DeserializationException { try { /* @@ -215,54 +286,60 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto * InstanceIdentifier has definition InstanceIdentifier, * this means '?' is always  . Eclipse compiler * is able to determine this relationship and treats - * Entry,DataObject> and Entry + * Entry, DataObject> and Entry * as assignable. However openjdk / oracle javac treats this two types * as incompatible and issues a compile error. * *

- * It is safe to loose generic information and cast it to other generic signature. - * + * It is safe to lose generic information and cast it to other generic signature. */ @SuppressWarnings("unchecked") final Entry, DataObject> binding = Entry.class.cast( codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue())); - return Optional.fromNullable(binding); + return Optional.ofNullable(binding); } catch (final IllegalArgumentException e) { - return Optional.absent(); + return Optional.empty(); } } @Override - public void onGlobalContextUpdated(final SchemaContext arg0) { - runtimeContext = BindingRuntimeContext.create(classLoadingStrategy, arg0); + public void onGlobalContextUpdated(final SchemaContext context) { + final BindingRuntimeContext runtimeContext = BindingRuntimeContext.create(classLoadingStrategy, context); codecRegistry.onBindingRuntimeContextUpdated(runtimeContext); - if (futureSchema != null) { - futureSchema.onRuntimeContextUpdated(runtimeContext); - } + futureSchema.onRuntimeContextUpdated(runtimeContext); } - public Function>, Optional> - deserializeFunction(final InstanceIdentifier path) { - return codecRegistry.deserializeFunction(path); + /** + * Deprecated. + * + * @deprecated Use {@link BindingNormalizedNodeCodecRegistry#deserializeFunction} instead. + */ + @Deprecated + public final Function>, Optional> deserializeFunction( + final InstanceIdentifier path) { + return codecRegistry.deserializeFunction(path)::apply; } - public BindingNormalizedNodeCodecRegistry getCodecRegistry() { + public final BindingNormalizedNodeCodecRegistry getCodecRegistry() { return codecRegistry; } @Override + @PreDestroy public void close() { - // NOOP Intentionally + if (listenerRegistration != null) { + listenerRegistration.close(); + } } - public BindingNormalizedNodeCodecRegistry getCodecFactory() { + public final BindingNormalizedNodeCodecRegistry getCodecFactory() { return codecRegistry; } // FIXME: This should be probably part of Binding Runtime context - public ImmutableBiMap getRpcMethodToSchemaPath(final Class key) { + public final ImmutableBiMap getRpcMethodToSchemaPath(final Class key) { final Module module = getModuleBlocking(key); - final ImmutableBiMap.Builder ret = ImmutableBiMap.builder(); + final ImmutableBiMap.Builder ret = ImmutableBiMap.builder(); try { for (final RpcDefinition rpcDef : module.getRpcs()) { final Method method = findRpcMethod(key, rpcDef); @@ -290,122 +367,126 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto private Module getModuleBlocking(final Class modeledClass) { final QNameModule moduleName = BindingReflections.getQNameModule(modeledClass); - final URI namespace = moduleName.getNamespace(); - final Date revision = moduleName.getRevision(); - BindingRuntimeContext localRuntimeContext = runtimeContext; + BindingRuntimeContext localRuntimeContext = runtimeContext(); Module module = localRuntimeContext == null ? null : - localRuntimeContext.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision); - if (module == null && futureSchema != null && futureSchema.waitForSchema(namespace,revision)) { - localRuntimeContext = runtimeContext; - Preconditions.checkState(localRuntimeContext != null, "BindingRuntimeContext is not available."); - module = localRuntimeContext.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision); + localRuntimeContext.getSchemaContext().findModule(moduleName).orElse(null); + if (module == null && futureSchema.waitForSchema(moduleName)) { + localRuntimeContext = runtimeContext(); + checkState(localRuntimeContext != null, "BindingRuntimeContext is not available."); + module = localRuntimeContext.getSchemaContext().findModule(moduleName).orElse(null); + } + if (module != null) { + return module; } - Preconditions.checkState(module != null, "Schema for %s is not available.", modeledClass); - return module; + + LOG.debug("Schema for {} is not available; expected module name: {}; BindingRuntimeContext: {}", + modeledClass, moduleName, localRuntimeContext); + throw new IllegalStateException(String.format("Schema for %s is not available; expected module name: %s; " + + "full BindingRuntimeContext available in debug log", modeledClass, moduleName)); } private void waitForSchema(final Collection> binding, final MissingSchemaException exception) { - if (futureSchema != null) { - LOG.warn("Blocking thread to wait for schema convergence updates for {} {}", - futureSchema.getDuration(), futureSchema.getUnit()); - if (!futureSchema.waitForSchema(binding)) { - return; - } + LOG.warn("Blocking thread to wait for schema convergence updates for {} {}", futureSchema.getDuration(), + futureSchema.getUnit()); + if (!futureSchema.waitForSchema(binding)) { + throw exception; } - throw exception; } private Method findRpcMethod(final Class key, final RpcDefinition rpcDef) throws NoSuchMethodException { - final String methodName = BindingMapping.getMethodName(rpcDef.getQName()); - if (rpcDef.getInput() != null) { - final Class inputClz = runtimeContext.getClassForSchema(rpcDef.getInput()); - return key.getMethod(methodName, inputClz); - } - return key.getMethod(methodName); + final String methodName = BindingMapping.getRpcMethodName(rpcDef.getQName()); + final Class inputClz = runtimeContext().getClassForSchema(rpcDef.getInput()); + return key.getMethod(methodName, inputClz); } @Override - public BindingCodecTree create(final BindingRuntimeContext context) { + public final BindingCodecTree create(final BindingRuntimeContext context) { return codecRegistry.create(context); } @Override - public BindingCodecTree create(final SchemaContext context, final Class... bindingClasses) { + public final BindingCodecTree create(final SchemaContext context, final Class... bindingClasses) { return codecRegistry.create(context, bindingClasses); } - @Nonnull - protected Map.Entry, BindingCodecTreeNode> getSubtreeCodec( + protected @NonNull Entry, BindingDataObjectCodecTreeNode> getSubtreeCodec( final YangInstanceIdentifier domIdentifier) { final BindingCodecTree currentCodecTree = codecRegistry.getCodecContext(); final InstanceIdentifier bindingPath = codecRegistry.fromYangInstanceIdentifier(domIdentifier); - Preconditions.checkArgument(bindingPath != null); + checkArgument(bindingPath != null); /** * If we are able to deserialize YANG instance identifier, getSubtreeCodec must * return non-null value. */ - final BindingCodecTreeNode codecContext = currentCodecTree.getSubtreeCodec(bindingPath); + final BindingDataObjectCodecTreeNode codecContext = currentCodecTree.getSubtreeCodec(bindingPath); return new SimpleEntry<>(bindingPath, codecContext); } @SuppressWarnings("unchecked") - public Set> getNotificationClasses(final Set interested) { + public final Set> getNotificationClasses(final Set interested) { final Set> result = new HashSet<>(); - final Set knownNotifications = runtimeContext.getSchemaContext().getNotifications(); - for (final NotificationDefinition notification : knownNotifications) { + final BindingRuntimeContext runtimeContext = runtimeContext(); + for (final NotificationDefinition notification : runtimeContext.getSchemaContext().getNotifications()) { if (interested.contains(notification.getPath())) { try { result.add((Class) runtimeContext.getClassForSchema(notification)); } catch (final IllegalStateException e) { // Ignore - LOG.warn("Class for {} is currently not known.",notification.getPath(),e); + LOG.warn("Class for {} is currently not known.", notification.getPath(), e); } } } return result; } + SchemaPath getActionPath(final Class> type) { + final ActionDefinition schema = runtimeContext().getActionDefinition(type); + checkArgument(schema != null, "Failed to find schema for %s", type); + return schema.getPath(); + } + + private BindingRuntimeContext runtimeContext() { + return futureSchema.runtimeContext(); + } + private static Collection> decompose(final InstanceIdentifier path) { - final Set> clazzes = new HashSet<>(); - for (final InstanceIdentifier.PathArgument arg : path.getPathArguments()) { - clazzes.add(arg.getType()); - } - return clazzes; + return ImmutableSet.copyOf(Iterators.transform(path.getPathArguments().iterator(), PathArgument::getType)); } protected NormalizedNode instanceIdentifierToNode(final YangInstanceIdentifier parentPath) { - return ImmutableNodes.fromInstanceId(runtimeContext.getSchemaContext(), parentPath); + return ImmutableNodes.fromInstanceId(runtimeContext().getSchemaContext(), parentPath); } + /** + * This method creates an empty list container of a particular type. + * + * @deprecated This method is not generally useful, as empty lists do not convey information in YANG (they are + * equivalent to non-present lists). It also leaks implementation details to a broader scope and should + * never have been public in the first place. + */ + @Deprecated public NormalizedNode getDefaultNodeFor(final YangInstanceIdentifier parentMapPath) { - final BindingCodecTreeNode mapCodec = codecRegistry.getCodecContext().getSubtreeCodec(parentMapPath); - final Object schema = mapCodec.getSchema(); + final BindingCodecTreeNode mapCodec = requireNonNull( + codecRegistry.getCodecContext().getSubtreeCodec(parentMapPath), + "Codec not found for yang instance identifier: " + parentMapPath); + final WithStatus schema = mapCodec.getSchema(); if (schema instanceof ListSchemaNode) { final ListSchemaNode castedSchema = (ListSchemaNode) schema; - if (castedSchema.isUserOrdered()) { - return Builders.orderedMapBuilder(castedSchema).build(); - } else { - return Builders.mapBuilder(castedSchema).build(); - } + return castedSchema.isUserOrdered() ? Builders.orderedMapBuilder(castedSchema).build() + : Builders.mapBuilder(castedSchema).build(); } throw new IllegalArgumentException("Path does not point to list schema node"); } protected Collection toDOMDataTreeIdentifiers( final Collection> subtrees) { - final Set ret = new HashSet<>(subtrees.size()); - - for (final DataTreeIdentifier subtree : subtrees) { - ret.add(toDOMDataTreeIdentifier(subtree)); - } - return ret; + return subtrees.stream().map(this::toDOMDataTreeIdentifier).collect(Collectors.toSet()); } protected DOMDataTreeIdentifier toDOMDataTreeIdentifier(final DataTreeIdentifier path) { final YangInstanceIdentifier domPath = toYangInstanceIdentifierBlocking(path.getRootIdentifier()); return new DOMDataTreeIdentifier(path.getDatastoreType(), domPath); } - }