BUG-4261: make ImmutableNormalizedNodeStreamWriter DataSchemaNodeAware 47/28247/3
authorRobert Varga <rovarga@cisco.com>
Fri, 9 Oct 2015 17:56:47 +0000 (19:56 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 12 Oct 2015 08:53:50 +0000 (08:53 +0000)
ImmutableNormalizedNodeStreamWriter can perform leaf node interning when
it knows what the schema is. Turn it into a DataSchemaNodeAware, so
users can pass down this information and make use of it when adding
leaves.

Change-Id: I7566a8705c0a05ea3cfa1335c7335021de6edccc
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNormalizedNodeStreamWriter.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InterningLeafSetNodeBuilder.java [new file with mode: 0644]

index c0f800f07f2031b1116d36e9d149d5bc8fcaa632..a8d1d723debced755e0c8dbde6fb74fb1b0f15c6 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
@@ -25,6 +26,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.SchemaAwareNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
@@ -40,6 +42,9 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMa
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.util.LeafInterner;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 
 /**
  *
@@ -54,10 +59,11 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUn
  *
  *
  */
-public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
+public class ImmutableNormalizedNodeStreamWriter implements SchemaAwareNormalizedNodeStreamWriter {
 
     @SuppressWarnings("rawtypes")
     private final Deque<NormalizedNodeContainerBuilder> builders = new ArrayDeque<>();
+    private DataSchemaNode nextSchema;
 
     @SuppressWarnings("rawtypes")
     protected ImmutableNormalizedNodeStreamWriter(final NormalizedNodeContainerBuilder topLevelBuilder) {
@@ -84,7 +90,6 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
     }
 
     /**
-     *
      * Creates a {@link NormalizedNodeStreamWriter} which creates one instance of top
      * level {@link NormalizedNode} (type of NormalizedNode) is determined by first
      * start event.
@@ -106,7 +111,6 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
         return new ImmutableNormalizedNodeStreamWriter(result);
     }
 
-
     @SuppressWarnings("rawtypes")
     private NormalizedNodeContainerBuilder getCurrent() {
         return builders.peek();
@@ -115,6 +119,7 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
     @SuppressWarnings("rawtypes")
     private void enter(final NormalizedNodeContainerBuilder next) {
         builders.push(next);
+        nextSchema = null;
     }
 
     @SuppressWarnings("unchecked")
@@ -131,19 +136,31 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
         Preconditions.checkState(current != null, "Reached top level node, which could not be closed in this writer.");
         final NormalizedNode<PathArgument, ?> product = finishedBuilder.build();
         current.addChild(product);
+        nextSchema = null;
     }
 
     @Override
     public void leafNode(final NodeIdentifier name, final Object value) {
         checkDataNodeContainer();
-        writeChild(ImmutableNodes.leafNode(name, value));
+
+        final LeafNode<Object> sample = ImmutableNodes.leafNode(name, value);
+        final LeafNode<Object> node;
+        if (nextSchema instanceof LeafSchemaNode) {
+            node = LeafInterner.forSchema((LeafSchemaNode)nextSchema).intern(sample);
+        } else {
+            node = sample;
+        }
+
+        writeChild(node);
+        nextSchema = null;
     }
 
     @Override
     public void startLeafSet(final NodeIdentifier name, final int childSizeHint) {
         checkDataNodeContainer();
         final ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = UNKNOWN_SIZE == childSizeHint ?
-                ImmutableLeafSetNodeBuilder.create() : ImmutableLeafSetNodeBuilder.create(childSizeHint);
+                InterningLeafSetNodeBuilder.create(nextSchema) :
+                    InterningLeafSetNodeBuilder.create(nextSchema, childSizeHint);
         builder.withNodeIdentifier(name);
         enter(builder);
     }
@@ -154,11 +171,13 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
         @SuppressWarnings("unchecked")
         final ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = ((ImmutableLeafSetNodeBuilder<Object>) getCurrent());
         builder.withChildValue(value);
+        nextSchema = null;
     }
 
     @Override
     public void anyxmlNode(final NodeIdentifier name, final Object value) {
         checkDataNodeContainer();
+        nextSchema = null;
     }
 
     @Override
@@ -293,4 +312,9 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
     public void close() {
         // no-op
     }
+
+    @Override
+    public void nextDataSchemaNode(final DataSchemaNode schema) {
+        nextSchema = Preconditions.checkNotNull(schema);
+    }
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InterningLeafSetNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InterningLeafSetNodeBuilder.java
new file mode 100644 (file)
index 0000000..4490829
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.util.LeafsetEntryInterner;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+
+final class InterningLeafSetNodeBuilder<T> extends ImmutableLeafSetNodeBuilder<T> {
+    private final LeafsetEntryInterner interner;
+
+    private InterningLeafSetNodeBuilder(final LeafsetEntryInterner interner) {
+        this.interner = Preconditions.checkNotNull(interner);
+    }
+
+    private InterningLeafSetNodeBuilder(final LeafsetEntryInterner interner, final int sizeHint) {
+        super(sizeHint);
+        this.interner = Preconditions.checkNotNull(interner);
+    }
+
+    private static LeafsetEntryInterner getInterner(final DataSchemaNode schema) {
+        return schema instanceof LeafSetNode ? LeafsetEntryInterner.forSchema((LeafListSchemaNode) schema) : null;
+    }
+
+    static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(final DataSchemaNode schema) {
+        final LeafsetEntryInterner interner = getInterner(schema);
+        if (interner != null) {
+            return new InterningLeafSetNodeBuilder<>(interner);
+        }
+
+        return ImmutableLeafSetNodeBuilder.create();
+    }
+
+    static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(final DataSchemaNode schema, final int sizeHint) {
+        final LeafsetEntryInterner interner = getInterner(schema);
+        if (interner != null) {
+            return new InterningLeafSetNodeBuilder<>(interner, sizeHint);
+        }
+
+        return ImmutableLeafSetNodeBuilder.create(sizeHint);
+    }
+
+    @Override
+    public ListNodeBuilder<T, LeafSetEntryNode<T>> withChild(final LeafSetEntryNode<T> child) {
+        return super.withChild(interner.intern(child));
+    }
+}