Promote codec exceptions to binding.codec.api 54/87854/20
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 17 Feb 2020 23:53:20 +0000 (00:53 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 18 Feb 2020 16:49:29 +0000 (17:49 +0100)
This exception should be part of documented API contract, promote
it.

JIRA: MDSAL-392
Change-Id: Ia0985e0399468ee3f57a4a50f65b38085245edeb
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java
binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/IncorrectNestingException.java [moved from binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/IncorrectNestingException.java with 50% similarity]
binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingClassInLoadingStrategyException.java [moved from binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingClassInLoadingStrategyException.java with 50% similarity]
binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingSchemaException.java [new file with mode: 0644]
binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingSchemaForClassException.java [new file with mode: 0644]
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataContainerCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingSchemaException.java [deleted file]
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingSchemaForClassException.java [deleted file]
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/AugmentationClassDiscoveredAfterCodecTest.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/ExceptionReportingTest.java

index 55fde2cd655b19b5e47517d3ca0ec7895f84cf50..951d7c4c3e74be08ed966ef3e9601b24a12eecec 100644 (file)
@@ -39,8 +39,8 @@ 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.api.MissingSchemaException;
 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;
@@ -5,36 +5,24 @@
  * 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.mdsal.binding.dom.codec.impl;
+package org.opendaylight.mdsal.binding.dom.codec.api;
 
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
+import com.google.common.annotations.Beta;
 
 /**
- * Thrown where incorrect nesting of data structures was detected and was caused by user.
+ * Thrown where incorrect nesting of data structures was detected and was caused by user. This typically indicates
+ * that class structure encountered could not have possibly been constructed according to the rules understood by the
+ * codec.
  */
+@Beta
 public class IncorrectNestingException extends IllegalArgumentException {
-
     private static final long serialVersionUID = 1L;
 
-    protected IncorrectNestingException(final String message) {
+    public IncorrectNestingException(final String message) {
         super(message);
     }
 
     public static IncorrectNestingException create(final String message, final Object... args) {
         return new IncorrectNestingException(String.format(message, args));
     }
-
-    public static void check(final boolean check, final String message, final Object... args) {
-        if (!check) {
-            throw IncorrectNestingException.create(message, args);
-        }
-    }
-
-    public static <V> @NonNull V checkNonNull(final @Nullable V nullable, final String message, final Object... args) {
-        if (nullable != null) {
-            return nullable;
-        }
-        throw IncorrectNestingException.create(message, args);
-    }
 }
@@ -5,30 +5,20 @@
  * 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.mdsal.binding.dom.codec.impl;
+package org.opendaylight.mdsal.binding.dom.codec.api;
 
-import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
+import com.google.common.annotations.Beta;
 
 /**
  * Thrown when user schema for supplied binding class is available in present schema context, but
  * binding class itself is not known to codecs because backing class loading strategy did not
  * provided it.
  */
+@Beta
 public class MissingClassInLoadingStrategyException extends MissingSchemaException {
-
     private static final long serialVersionUID = 1L;
 
-    protected MissingClassInLoadingStrategyException(final String msg, final Throwable cause) {
+    public MissingClassInLoadingStrategyException(final String msg, final Throwable cause) {
         super(msg, cause);
     }
-
-    public static void check(final ClassLoadingStrategy strategy, final Class<?> childClass) {
-        try {
-            strategy.loadClass(childClass.getName());
-        } catch (final ClassNotFoundException e) {
-            final String message =
-                    String.format("User supplied class %s is not available in %s.", childClass.getName(), strategy);
-            throw new MissingClassInLoadingStrategyException(message, e);
-        }
-    }
 }
diff --git a/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingSchemaException.java b/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingSchemaException.java
new file mode 100644 (file)
index 0000000..911bd5d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.mdsal.binding.dom.codec.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Thrown when codec was used with data which are not modeled and available in schema used by codec.
+ */
+@Beta
+public class MissingSchemaException extends IllegalArgumentException {
+    private static final long serialVersionUID = 1L;
+
+    public MissingSchemaException(final String msg) {
+        super(msg);
+    }
+
+    public MissingSchemaException(final String msg, final Throwable cause) {
+        super(msg, cause);
+    }
+}
diff --git a/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingSchemaForClassException.java b/binding/mdsal-binding-dom-codec-api/src/main/java/org/opendaylight/mdsal/binding/dom/codec/api/MissingSchemaForClassException.java
new file mode 100644 (file)
index 0000000..31d8967
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.mdsal.binding.dom.codec.api;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * Thrown when Java Binding class was used in data for which codec does not have schema.
+ *
+ * <p>
+ * By serialization /  deserialization of this exception {@link #getBindingClass()} will return null.
+ */
+@Beta
+public final class MissingSchemaForClassException extends MissingSchemaException {
+    private static final long serialVersionUID = 1L;
+
+    @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Documented in API contract")
+    private final transient Class<?> bindingClass;
+
+    public MissingSchemaForClassException(final Class<?> clz) {
+        super(String.format("Schema is not available for %s", clz));
+        this.bindingClass = requireNonNull(clz);
+    }
+
+    public @Nullable Class<?> getBindingClass() {
+        return bindingClass;
+    }
+}
index 6624e3ab950938a228ae23c3b6fbb284a1e604af..a6ffaaedd8add1388084e8e04b3889a4203f5335 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ImmutableCollection;
@@ -16,17 +17,26 @@ import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingStreamEventWriter;
+import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
+import org.opendaylight.mdsal.binding.dom.codec.api.MissingClassInLoadingStrategyException;
+import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaException;
+import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaForClassException;
+import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BindingObject;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
 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.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
@@ -158,32 +168,69 @@ abstract class DataContainerCodecContext<D extends DataObject, T extends WithSta
 
     protected final <V> @NonNull V childNonNull(final @Nullable V nullable,
             final YangInstanceIdentifier.PathArgument child, final String message, final Object... args) {
-        if (nullable != null) {
-            return nullable;
+        if (nullable == null) {
+            throw childNullException(extractName(child), message, args);
         }
-        MissingSchemaException.checkModulePresent(factory().getRuntimeContext().getSchemaContext(), child);
-        throw IncorrectNestingException.create(message, args);
+        return nullable;
     }
 
     protected final <V> @NonNull V childNonNull(final @Nullable V nullable, final QName child, final String message,
             final Object... args) {
-        if (nullable != null) {
-            return nullable;
+        if (nullable == null) {
+            throw childNullException(child, message, args);
         }
-        MissingSchemaException.checkModulePresent(factory().getRuntimeContext().getSchemaContext(), child);
-        throw IncorrectNestingException.create(message, args);
+        return nullable;
     }
 
     protected final <V> @NonNull V childNonNull(final @Nullable V nullable, final Class<?> childClass,
             final String message, final Object... args) {
-        if (nullable != null) {
-            return nullable;
+        if (nullable == null) {
+            throw childNullException(childClass, message, args);
+        }
+        return nullable;
+    }
+
+    private IllegalArgumentException childNullException(final QName child, final String message, final Object... args) {
+        final QNameModule module = child.getModule();
+        if (!factory().getRuntimeContext().getSchemaContext().findModule(module).isPresent()) {
+            throw new MissingSchemaException("Module " + module + " is not present in current schema context.");
+        }
+        throw IncorrectNestingException.create(message, args);
+    }
+
+    private IllegalArgumentException childNullException(final Class<?> childClass, final String message,
+            final Object... args) {
+        final BindingRuntimeContext runtimeContext = factory().getRuntimeContext();
+        final WithStatus schema;
+        if (Augmentation.class.isAssignableFrom(childClass)) {
+            schema = runtimeContext.getAugmentationDefinition(childClass);
+        } else {
+            schema = runtimeContext.getSchemaDefinition(childClass);
+        }
+        if (schema == null) {
+            throw new MissingSchemaForClassException(childClass);
+        }
+
+        final ClassLoadingStrategy strategy = runtimeContext.getStrategy();
+        try {
+            strategy.loadClass(childClass.getName());
+        } catch (final ClassNotFoundException e) {
+            throw new MissingClassInLoadingStrategyException(
+                "User supplied class " + childClass.getName() + " is not available in " + strategy, e);
         }
-        MissingSchemaForClassException.check(factory().getRuntimeContext(), childClass);
-        MissingClassInLoadingStrategyException.check(factory().getRuntimeContext().getStrategy(), childClass);
+
         throw IncorrectNestingException.create(message, args);
     }
 
+    private static QName extractName(final YangInstanceIdentifier.PathArgument child) {
+        if (child instanceof AugmentationIdentifier) {
+            final Set<QName> children = ((AugmentationIdentifier) child).getPossibleChildNames();
+            checkArgument(!children.isEmpty(), "Augmentation without childs must not be used in data");
+            return children.iterator().next();
+        }
+        return child.getNodeType();
+    }
+
     final DataObjectSerializer eventStreamSerializer() {
         final DataObjectSerializer existing = (DataObjectSerializer) EVENT_STREAM_SERIALIZER.getAcquire(this);
         return existing != null ? existing : loadEventStreamSerializer();
index 67cb8716d2975556bdac791f5c834d19bd4a6236..c213188daea222b56a2150be4d783b71b57d4a8b 100644 (file)
@@ -28,6 +28,7 @@ import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
 import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
 import org.opendaylight.mdsal.binding.model.api.Type;
@@ -335,7 +336,10 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Dat
 
     protected final ValueNodeCodecContext getLeafChild(final String name) {
         final ValueNodeCodecContext value = leafChild.get(name);
-        return IncorrectNestingException.checkNonNull(value, "Leaf %s is not valid for %s", name, getBindingClass());
+        if (value == null) {
+            throw IncorrectNestingException.create("Leaf %s is not valid for %s", name, getBindingClass());
+        }
+        return value;
     }
 
     private DataContainerCodecPrototype<?> loadChildPrototype(final Class<?> childClass) {
diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingSchemaException.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingSchemaException.java
deleted file mode 100644 (file)
index 3634d7f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.mdsal.binding.dom.codec.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Set;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Thrown when codec was used with data which are not modeled and available in schema used by codec.
- */
-public class MissingSchemaException extends IllegalArgumentException {
-
-    private static final long serialVersionUID = 1L;
-
-    protected MissingSchemaException(final String msg) {
-        super(msg);
-    }
-
-    protected MissingSchemaException(final String msg, final Throwable cause) {
-        super(msg, cause);
-    }
-
-    private static MissingSchemaException create(final String format, final Object... args) {
-        return new MissingSchemaException(String.format(format, args));
-    }
-
-    static void checkModulePresent(final SchemaContext schemaContext, final QName name) {
-        if (!schemaContext.findModule(name.getModule()).isPresent()) {
-            throw MissingSchemaException.create("Module %s is not present in current schema context.",
-                name.getModule());
-        }
-    }
-
-    static void checkModulePresent(final SchemaContext schemaContext, final PathArgument child) {
-        checkModulePresent(schemaContext, extractName(child));
-    }
-
-    private static QName extractName(final PathArgument child) {
-        if (child instanceof AugmentationIdentifier) {
-            final Set<QName> children = ((AugmentationIdentifier) child).getPossibleChildNames();
-            Preconditions.checkArgument(!children.isEmpty(),"Augmentation without childs must not be used in data");
-            return children.iterator().next();
-        }
-        return child.getNodeType();
-    }
-}
diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingSchemaForClassException.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/MissingSchemaForClassException.java
deleted file mode 100644 (file)
index 6e92a5a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.mdsal.binding.dom.codec.impl;
-
-import static java.util.Objects.requireNonNull;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-
-/**
- * Thrown when Java Binding class was used in data for which codec does not have schema.
- *
- * <p>
- * By serialization /  deserialization of this exception {@link #getBindingClass()} will return null.
- */
-public final class MissingSchemaForClassException extends MissingSchemaException {
-
-    private static final long serialVersionUID = 1L;
-
-    @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
-    private final transient Class<?> bindingClass;
-
-    private MissingSchemaForClassException(final Class<?> clz) {
-        super(String.format("Schema is not available for %s", clz));
-        this.bindingClass = requireNonNull(clz);
-    }
-
-    static MissingSchemaForClassException forClass(final Class<?> clz) {
-        return new MissingSchemaForClassException(clz);
-    }
-
-    public Class<?> getBindingClass() {
-        return bindingClass;
-    }
-
-    public static void check(final BindingRuntimeContext runtimeContext, final Class<?> bindingClass) {
-        final Object schema;
-        if (Augmentation.class.isAssignableFrom(bindingClass)) {
-            schema = runtimeContext.getAugmentationDefinition(bindingClass);
-        } else {
-            schema = runtimeContext.getSchemaDefinition(bindingClass);
-        }
-        if (schema == null) {
-            throw MissingSchemaForClassException.forClass(bindingClass);
-        }
-    }
-}
index 297d59ae7cf2ff613cf20cb75e05582b5a14cacd..83d0db0f06a2cc1f4900e571bbf6f10cbd905730 100644 (file)
@@ -15,8 +15,8 @@ import java.util.Map.Entry;
 import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.mdsal.binding.dom.codec.api.MissingClassInLoadingStrategyException;
 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.mdsal.binding.dom.codec.impl.MissingClassInLoadingStrategyException;
 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
index f1be7157d49c15160fd25627f1b7a0765db57642..c6bdaf6560defd7403e1efb51afdf6795b010d6a 100644 (file)
@@ -8,10 +8,10 @@
 package org.opendaylight.mdsal.binding.dom.codec.test;
 
 import org.junit.Test;
+import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
+import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaException;
+import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaForClassException;
 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.mdsal.binding.dom.codec.impl.IncorrectNestingException;
-import org.opendaylight.mdsal.binding.dom.codec.impl.MissingSchemaException;
-import org.opendaylight.mdsal.binding.dom.codec.impl.MissingSchemaForClassException;
 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;