NormalizedMetadata is not Identifiable 52/106052/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 18 May 2023 20:42:21 +0000 (22:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 18 May 2023 20:44:08 +0000 (22:44 +0200)
We are going for a place where the root node, and hence the top-level
NormalizedMetadata is does not have a PathArgument. Eliminate the idea
that there is a getIdentifier(), reflecting the design of
NormalizedMountpoints back.

JIRA: NETCONF-1472
Change-Id: I5bab85a933bf3bc4d63d41db081c9399d3e13894
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
data/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/NormalizedMetadata.java
data/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableMetadataNormalizedNodeStreamWriter.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ImmutableNormalizedMetadata.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ImmutableNormalizedMetadataStreamWriter.java
data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/NormalizedMetadataWriter.java

index 07d263897e060035c1e8891a1736478bbb5de5cf..791f7285ca1aa8c3ee5385a8eb8cede27b9d3114 100644 (file)
@@ -11,7 +11,6 @@ import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableMap;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
@@ -25,11 +24,9 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
  * This model of metadata <em>does not</em> have the RFC7952 restriction on metadata attachment to {@code list}s and
  * {@code leaf-list}s because NormalizedNode data model has {@link LeafSetNode}, {@link MapNode} and
  * {@link UnkeyedListNode} to which metadata can be attached.
- *
- * @author Robert Varga
  */
 @Beta
-public interface NormalizedMetadata extends Identifiable<PathArgument>, Immutable {
+public interface NormalizedMetadata extends Immutable {
     /**
      * Return the set of annotations defined in this metadata node. Values are expected to be effectively-immutable
      * scalar types, like {@link String}s, {@link Number}s and similar. The map must also be effectively-immutable.
index c63674a3c13fbb4265be0a0eac00f461c7ab9903..56061972ca81f4013a807419f3e78db11e2ceaab 100644 (file)
@@ -17,6 +17,7 @@ import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedMetadata;
@@ -36,10 +37,10 @@ public class ImmutableMetadataNormalizedNodeStreamWriter extends ImmutableNormal
      * Snapshot of currently-open data- and metadatastate.
      */
     public static final class State {
-        final Builder metaBuilder;
+        final BuilderEntry metaBuilder;
         final NormalizedNodeBuilder dataBuilder;
 
-        State(final NormalizedNodeBuilder dataBuilder, final Builder metadataBuilder) {
+        State(final NormalizedNodeBuilder dataBuilder, final BuilderEntry metadataBuilder) {
             this.dataBuilder = requireNonNull(dataBuilder);
             metaBuilder = requireNonNull(metadataBuilder);
         }
@@ -49,16 +50,24 @@ public class ImmutableMetadataNormalizedNodeStreamWriter extends ImmutableNormal
         }
 
         public Builder getMetaBuilder() {
-            return metaBuilder;
+            return metaBuilder.builder;
         }
     }
 
-    private final Deque<Builder> builders = new ArrayDeque<>();
+    @NonNullByDefault
+    private record BuilderEntry(PathArgument identifier, Builder builder) {
+        BuilderEntry {
+            requireNonNull(identifier);
+            requireNonNull(builder);
+        }
+    }
+
+    private final Deque<BuilderEntry> builders = new ArrayDeque<>();
     private final NormalizationResultHolder holder;
 
     protected ImmutableMetadataNormalizedNodeStreamWriter(final State state) {
-        super(state.getDataBuilder());
-        builders.push(state.getMetaBuilder());
+        super(state.dataBuilder);
+        builders.push(state.metaBuilder);
         holder = null;
     }
 
@@ -74,9 +83,9 @@ public class ImmutableMetadataNormalizedNodeStreamWriter extends ImmutableNormal
 
     @Override
     public final void metadata(final ImmutableMap<QName, Object> metadata) throws IOException {
-        final Builder current = builders.peek();
+        final var current = builders.peek();
         checkState(current != null, "Attempted to emit metadata when no metadata is open");
-        current.withAnnotations(metadata);
+        current.builder.withAnnotations(metadata);
     }
 
     /**
@@ -92,17 +101,19 @@ public class ImmutableMetadataNormalizedNodeStreamWriter extends ImmutableNormal
     @SuppressWarnings("rawtypes")
     final void enter(final PathArgument identifier, final NormalizedNodeBuilder next) {
         super.enter(identifier, next);
-        builders.push(ImmutableNormalizedMetadata.builder().withIdentifier(identifier));
+        builders.push(new BuilderEntry(identifier, ImmutableNormalizedMetadata.builder()));
     }
 
     @Override
     public final void endNode() {
         super.endNode();
-        final ImmutableNormalizedMetadata metadata = builders.pop().build();
-        final Builder current = builders.peek();
+
+        final var last = builders.pop();
+        final var metadata = last.builder.build();
+        final var current = builders.peek();
         if (current != null) {
             if (!metadata.getAnnotations().isEmpty() || !metadata.getChildren().isEmpty()) {
-                current.withChild(metadata);
+                current.builder.withChild(last.identifier, metadata);
             }
         } else {
             // All done
index 957e2c85594ff13091fbcabcad3fb3863c69071d..0aea3fea4e392ead48e71e8fd41554237d55415e 100644 (file)
@@ -7,15 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.util;
 
-import static com.google.common.base.Preconditions.checkState;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ImmutableMap;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.AbstractSimpleIdentifiable;
 import org.opendaylight.yangtools.concepts.Mutable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
@@ -24,14 +21,13 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedMetadata;
 /**
  * Immutable implementation of {@link NormalizedMetadata}.
  */
-public sealed class ImmutableNormalizedMetadata extends AbstractSimpleIdentifiable<PathArgument>
-        implements NormalizedMetadata {
+public sealed class ImmutableNormalizedMetadata implements NormalizedMetadata {
     private static final class Container extends ImmutableNormalizedMetadata {
         private final @NonNull ImmutableMap<PathArgument, NormalizedMetadata> children;
 
-        Container(final PathArgument identifier, final Map<QName, Object> annotations,
+        Container(final Map<QName, Object> annotations,
                 final Map<PathArgument, ImmutableNormalizedMetadata> children) {
-            super(identifier, annotations);
+            super(annotations);
             this.children = ImmutableMap.copyOf(children);
         }
 
@@ -43,8 +39,7 @@ public sealed class ImmutableNormalizedMetadata extends AbstractSimpleIdentifiab
 
     private final @NonNull ImmutableMap<QName, Object> annotations;
 
-    ImmutableNormalizedMetadata(final @NonNull PathArgument identifier, final Map<QName, Object> annotations) {
-        super(identifier);
+    ImmutableNormalizedMetadata(final Map<QName, Object> annotations) {
         this.annotations = ImmutableMap.copyOf(annotations);
     }
 
@@ -68,18 +63,11 @@ public sealed class ImmutableNormalizedMetadata extends AbstractSimpleIdentifiab
     public static final class Builder implements Mutable {
         private final Map<PathArgument, ImmutableNormalizedMetadata> children = new HashMap<>();
         private final Map<QName, Object> annotations = new HashMap<>();
-        private PathArgument identifier;
 
         Builder() {
             // Hidden to prevent instantiation
         }
 
-        @SuppressWarnings("checkstyle:hiddenField")
-        public @NonNull Builder withIdentifier(final PathArgument identifier) {
-            this.identifier = requireNonNull(identifier);
-            return this;
-        }
-
         public @NonNull Builder withAnnotation(final QName type, final Object value) {
             annotations.put(requireNonNull(type, "type"), requireNonNull(value, "value"));
             return this;
@@ -91,13 +79,13 @@ public sealed class ImmutableNormalizedMetadata extends AbstractSimpleIdentifiab
             return this;
         }
 
-        public @NonNull Builder withChild(final ImmutableNormalizedMetadata child) {
-            children.put(child.getIdentifier(), child);
+        public @NonNull Builder withChild(final PathArgument pathArgument, final ImmutableNormalizedMetadata child) {
+            children.put(requireNonNull(pathArgument, "pathArgument"), requireNonNull(child, "child"));
             return this;
         }
 
         @SuppressWarnings("checkstyle:hiddenField")
-        public @NonNull Builder withChildren(final Collection<ImmutableNormalizedMetadata> children) {
+        public @NonNull Builder withChildren(final Map<PathArgument, ImmutableNormalizedMetadata> children) {
             children.forEach(this::withChild);
             return this;
         }
@@ -109,10 +97,8 @@ public sealed class ImmutableNormalizedMetadata extends AbstractSimpleIdentifiab
          * @throws IllegalStateException if this builder does not have enough state
          */
         public @NonNull ImmutableNormalizedMetadata build() {
-            final PathArgument id = identifier;
-            checkState(id != null, "Identifier has not been set");
-            return children.isEmpty() ? new ImmutableNormalizedMetadata(id, annotations)
-                    : new Container(id, annotations, children);
+            return children.isEmpty() ? new ImmutableNormalizedMetadata(annotations)
+                : new Container(annotations, children);
         }
     }
 }
index 23e64a194567a8985ddb2b838e9d36294f309e5d..5268577f1c8335771f33f3bf614b199db1dc949d 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.yang.data.util;
 
 import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableMap;
@@ -15,6 +16,7 @@ import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedMetadata;
@@ -27,22 +29,32 @@ import org.opendaylight.yangtools.yang.data.util.ImmutableNormalizedMetadata.Bui
  */
 @Beta
 public final class ImmutableNormalizedMetadataStreamWriter implements MetadataExtension {
-    private final Deque<Builder> builders = new ArrayDeque<>();
+    @NonNullByDefault
+    private record BuilderEntry(PathArgument identifier, Builder builder) {
+        BuilderEntry {
+            requireNonNull(identifier);
+            requireNonNull(builder);
+        }
+    }
+
+    private final Deque<BuilderEntry> builders = new ArrayDeque<>();
 
     private ImmutableNormalizedMetadata result;
 
     public void enter(final PathArgument identifier) {
         checkNotDone();
-        builders.push(ImmutableNormalizedMetadata.builder().withIdentifier(identifier));
+        builders.push(new BuilderEntry(identifier, ImmutableNormalizedMetadata.builder()));
     }
 
     public void exit() {
         checkNotDone();
-        final ImmutableNormalizedMetadata metadata = builders.pop().build();
-        final Builder parent = builders.peek();
-        if (parent != null) {
-            if (!metadata.getAnnotations().isEmpty()) {
-                parent.withChild(metadata);
+
+        final var last = builders.pop();
+        final var metadata = last.builder.build();
+        final var current = builders.peek();
+        if (current != null) {
+            if (!metadata.getAnnotations().isEmpty() || !metadata.getChildren().isEmpty()) {
+                current.builder().withChild(last.identifier, metadata);
             }
         } else {
             result = metadata;
@@ -56,7 +68,7 @@ public final class ImmutableNormalizedMetadataStreamWriter implements MetadataEx
 
     @Override
     public void metadata(final ImmutableMap<QName, Object> metadata) throws IOException {
-        builders.peek().withAnnotations(metadata);
+        builders.peek().builder.withAnnotations(metadata);
     }
 
     private void checkNotDone() {
index 349a8040c372b4fc7f3e1ec9e391e80c9df1e0fd..020faf52bf4f4dea1d52ff426e97dbb72fd9ede7 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.data.util;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
@@ -15,7 +14,6 @@ import java.io.Closeable;
 import java.io.Flushable;
 import java.io.IOException;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedMetadata;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
@@ -96,20 +94,15 @@ public final class NormalizedMetadataWriter implements Closeable, Flushable {
      * @param metadata {@link NormalizedMetadata} metadata
      * @return NormalizedNodeWriter this
      * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if metadata does not match data
      * @throws IOException when thrown from the backing writer.
      */
     public @NonNull NormalizedMetadataWriter write(final NormalizedNode data, final NormalizedMetadata metadata)
             throws IOException {
-        final PathArgument dataId = data.name();
-        final PathArgument metaId = metadata.getIdentifier();
-        checkArgument(dataId.equals(metaId), "Mismatched data %s and metadata %s", dataId, metaId);
-
         final var metaWriter = writer.extension(MetadataExtension.class);
-        final NormalizedNodeStreamWriter delegate = metaWriter == null ? writer
+        final var delegate = metaWriter == null ? writer
                 : new NormalizedNodeStreamWriterMetadataDecorator(writer, metaWriter, metadata);
 
-        final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(delegate, orderKeyLeaves);
+        final var nnWriter = NormalizedNodeWriter.forStreamWriter(delegate, orderKeyLeaves);
         nnWriter.write(data);
         nnWriter.flush();
         return this;