Add uint adaptation to AbstractNormalizedNodePruner
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / datastore / node / utils / transformer / ReusableNormalizedNodePruner.java
index 1e95766f84901019cb69314555821d1af21be037..751c96f2b65f290429b91487bd3dbada16c71f4d 100644 (file)
@@ -8,10 +8,26 @@
 package org.opendaylight.controller.cluster.datastore.node.utils.transformer;
 
 import com.google.common.annotations.Beta;
+import java.io.IOException;
+import java.math.BigInteger;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The NormalizedNodePruner removes all nodes from the input NormalizedNode that do not have a corresponding
@@ -22,12 +38,62 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  * through {@link #initializeForPath(YangInstanceIdentifier)}.
  */
 @Beta
-public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePruner {
-    private ReusableNormalizedNodePruner(final SchemaContext schemaContext) {
+public abstract class ReusableNormalizedNodePruner extends AbstractNormalizedNodePruner {
+    private static final class SimplePruner extends ReusableNormalizedNodePruner {
+        SimplePruner(final SchemaContext schemaContext) {
+            super(schemaContext);
+        }
+
+        SimplePruner(final DataSchemaContextTree tree) {
+            super(tree);
+        }
+
+        @Override
+        public ReusableNormalizedNodePruner duplicate() {
+            return new SimplePruner(getTree());
+        }
+    }
+
+    private static final class UintAdaptingPruner extends ReusableNormalizedNodePruner {
+        private static final Logger LOG = LoggerFactory.getLogger(UintAdaptingPruner.class);
+
+        UintAdaptingPruner(final DataSchemaContextTree tree) {
+            super(tree);
+        }
+
+        @Override
+        public ReusableNormalizedNodePruner duplicate() {
+            return new UintAdaptingPruner(getTree());
+        }
+
+        @Override
+        Object translateScalar(final DataSchemaContextNode<?> context, final Object value) throws IOException {
+            final DataSchemaNode schema = context.getDataSchemaNode();
+            if (schema instanceof TypedDataSchemaNode) {
+                final TypeDefinition<?> type = ((TypedDataSchemaNode) schema).getType();
+                if (value instanceof Short && type instanceof Uint8TypeDefinition) {
+                    LOG.trace("Translating legacy uint8 {}", value);
+                    return Uint8.valueOf((Short) value);
+                } else if (value instanceof Integer && type instanceof Uint16TypeDefinition) {
+                    LOG.trace("Translating legacy uint16 {}", value);
+                    return Uint16.valueOf((Integer) value);
+                } else if (value instanceof Long && type instanceof Uint32TypeDefinition) {
+                    LOG.trace("Translating legacy uint32 {}", value);
+                    return Uint32.valueOf((Long) value);
+                } else if (value instanceof BigInteger && type instanceof Uint64TypeDefinition) {
+                    LOG.trace("Translating legacy uint64 {}", value);
+                    return Uint64.valueOf((BigInteger) value);
+                }
+            }
+            return value;
+        }
+    }
+
+    ReusableNormalizedNodePruner(final SchemaContext schemaContext) {
         super(schemaContext);
     }
 
-    private ReusableNormalizedNodePruner(final DataSchemaContextTree tree) {
+    ReusableNormalizedNodePruner(final DataSchemaContextTree tree) {
         super(tree);
     }
 
@@ -39,7 +105,7 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      * @throws NullPointerException if {@code schemaContext} is null
      */
     public static @NonNull ReusableNormalizedNodePruner forSchemaContext(final SchemaContext schemaContext) {
-        return new ReusableNormalizedNodePruner(schemaContext);
+        return new SimplePruner(schemaContext);
     }
 
     /**
@@ -51,7 +117,7 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      * @throws NullPointerException if {@code schemaContext} is null
      */
     public static @NonNull ReusableNormalizedNodePruner forDataSchemaContext(final DataSchemaContextTree tree) {
-        return new ReusableNormalizedNodePruner(tree);
+        return new SimplePruner(tree);
     }
 
     /**
@@ -61,9 +127,7 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      *
      * @return A new uninitialized pruner bound to the same SchemaContext as this one.
      */
-    public @NonNull ReusableNormalizedNodePruner duplicate() {
-        return new ReusableNormalizedNodePruner(getTree());
-    }
+    public abstract @NonNull ReusableNormalizedNodePruner duplicate();
 
     /**
      * Initialize this pruner for processing a node at specified path.
@@ -71,7 +135,11 @@ public final class ReusableNormalizedNodePruner extends AbstractNormalizedNodePr
      * @param path Path that will be processed next
      * @throws NullPointerException if {@code path} is null
      */
-    public void initializeForPath(final YangInstanceIdentifier path) {
+    public final void initializeForPath(final YangInstanceIdentifier path) {
         initialize(path);
     }
+
+    public final @NonNull ReusableNormalizedNodePruner withUintAdaption() {
+        return new UintAdaptingPruner(getTree());
+    }
 }