Add Augmentable.augmentationOrElseThrow()
[mdsal.git] / binding / yang-binding / src / main / java / org / opendaylight / yangtools / yang / binding / Augmentable.java
index e4575233e43b9f8062705bfc4f14fcadfd14da84..c74f63423c55d13391d42c47429b0a6a8de04d21 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.binding;
 
-import static java.util.Objects.requireNonNull;
-
 import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.function.Supplier;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 
@@ -26,16 +27,58 @@ import org.eclipse.jdt.annotation.Nullable;
  */
 public interface Augmentable<T> {
     /**
-     * Returns instance of augmentation.
+     * Returns instance of augmentation, if present.
      *
-     * @param augmentationType Type of augmentation to be returned.
      * @param <A> Type capture for augmentation type
-     * @return instance of augmentation, or null if the augmentationType is not present.
-     * @throws NullPointerException if augmentationType is null
+     * @param augmentationType Type of augmentation to be returned
+     * @return instance of {@code A}, or {@code null} if the augmentationType is not present
+     * @throws NullPointerException if {@code augmentationType} is {@code null}
      */
-    @SuppressWarnings("unchecked")
     default <A extends Augmentation<T>> @Nullable A augmentation(final Class<A> augmentationType) {
-        return (A) augmentations().get(requireNonNull(augmentationType));
+        return augmentationType.cast(augmentations().get(augmentationType));
+    }
+
+    /**
+     * Returns instance of augmentation, or throws {@link NoSuchElementException}.
+     *
+     * @param <A> Type capture for augmentation type
+     * @param augmentationType Type of augmentation to be returned
+     * @return An instance of {@code A}
+     * @throws NullPointerException if {@code augmentationType} is {@code null}
+     * @throws NoSuchElementException if the corresponding augmentation is not present
+     *
+     * @apiNote
+     *     The design here follows {@link Optional#orElseThrow()},
+     */
+    default <A extends Augmentation<T>> @NonNull A augmentationOrElseThrow(final Class<A> augmentationType) {
+        final var augmentation = augmentation(augmentationType);
+        if (augmentation != null) {
+            return augmentation;
+        }
+        throw new NoSuchElementException(augmentationType.getName() + " is not present in " + this);
+    }
+
+    /**
+     * Returns instance of augmentation, or throws {@link NoSuchElementException}.
+     *
+     * @param <A> Type capture for augmentation type
+     * @param <X> Type of the exception to be thrown
+     * @param augmentationType Type of augmentation to be returned
+     * @param exceptionSupplier the supplying function that produces an exception to be thrown
+     * @return An instance of {@code A}
+     * @throws NullPointerException if {@code augmentationType} is {@code null}
+     * @throws X if the corresponding augmentation is not present
+     *
+     * @apiNote
+     *     The design here follows {@link Optional#orElseThrow(Supplier)},
+     */
+    default <A extends Augmentation<T>, X extends Throwable> @NonNull A augmentationOrElseThrow(
+            final Class<A> augmentationType, final Supplier<@NonNull X> exceptionSupplier) throws X {
+        final var augmentation = augmentation(augmentationType);
+        if (augmentation != null) {
+            return augmentation;
+        }
+        throw exceptionSupplier.get();
     }
 
     /**