X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fyang-binding%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fbinding%2FCodeHelpers.java;h=be9ecbb8f52b39a9c84f4e460a36b7a073c756e7;hb=2840f8a13a244834a831614d96a1411b3add3286;hp=028543b2cd7cf216f7408f6935288660e512bf49;hpb=4c2b08900d7a4a06bf99698801f339c8bf22e07c;p=mdsal.git diff --git a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/CodeHelpers.java b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/CodeHelpers.java index 028543b2cd..be9ecbb8f5 100644 --- a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/CodeHelpers.java +++ b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/CodeHelpers.java @@ -15,9 +15,8 @@ import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.VerifyException; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Arrays; -import java.util.Collection; +import java.util.HexFormat; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -31,8 +30,6 @@ import org.eclipse.jdt.annotation.Nullable; * Helper methods for generated binding code. This class concentrates useful primitives generated code may call * to perform specific shared functions. This allows for generated classes to be leaner. Methods in this class follows * general API stability requirements of the Binding Specification. - * - * @author Robert Varga */ public final class CodeHelpers { private CodeHelpers() { @@ -52,13 +49,13 @@ public final class CodeHelpers { } /** - * Return value and check whether specified value is null and if so throws exception. This method supports + * Return value and check whether specified value is {@code null} and if so throws exception. This method supports * require default getter methods. * * @param value Value itself * @param name Name of the value * @return Non-null value - * @throws NoSuchElementException if value is null + * @throws NoSuchElementException if value is {@code null} */ public static @NonNull T require(final @Nullable T value, final @NonNull String name) { if (value == null) { @@ -73,7 +70,7 @@ public final class CodeHelpers { * @param value Value itself * @param name Name of the value * @return Non-null value - * @throws NullPointerException if value is null + * @throws NullPointerException if value is {@code null} */ public static @NonNull T requireKeyProp(final @Nullable T value, final @NonNull String name) { if (value == null) { @@ -86,19 +83,33 @@ public final class CodeHelpers { * A shortcut for {@code Objects.requireNonNull(value, "Supplied value may not be null")}. * * @param value Value itself - * @throws NullPointerException if value is null + * @throws NullPointerException if value is {@code null} */ public static void requireValue(final @Nullable Object value) { requireNonNull(value, "Supplied value may not be null"); } /** - * Append a named value to a ToStringHelper. If the value is null, this method does nothing. + * Append a {@code bits} individual value. If the value is {@code false}, this method does nothing. + * + * @param helper Helper to append to + * @param name Name of the bit + * @param value Value to append + * @throws NullPointerException if any argument is {@code null} + */ + public static void appendBit(final ToStringHelper helper, final @NonNull String name, final boolean value) { + if (value) { + helper.addValue(name); + } + } + + /** + * Append a named value to a ToStringHelper. If the value is {@code null}, this method does nothing. * * @param helper Helper to append to * @param name Name of the value * @param value Value to append - * @throws NullPointerException if the name or helper is null + * @throws NullPointerException if the name or helper is {@code null} */ public static void appendValue(final ToStringHelper helper, final @NonNull String name, final @Nullable Object value) { @@ -108,28 +119,27 @@ public final class CodeHelpers { } /** - * Append a named value to a ToStringHelper. If the value is null, this method does nothing. + * Append a named value to a ToStringHelper. If the value is {@code null}, this method does nothing. * * @param helper Helper to append to * @param name Name of the value * @param value Value to append - * @throws NullPointerException if the name or helper is null + * @throws NullPointerException if the name or helper is {@code null} */ public static void appendValue(final ToStringHelper helper, final String name, final byte[] value) { if (value != null) { - // FIXME: MDSAL-692: use hex-encoding instead - helper.add(name, Arrays.toString(value)); + helper.add(name, HexFormat.of().formatHex(value)); } } /** - * Append augmentation map of an Augmentable to a ToStringHelper. If augmentations are null or empt, this method - * does nothing. + * Append augmentation map of an Augmentable to a ToStringHelper. If augmentations are {@code null} or empty, this + * method does nothing. * * @param helper Helper to append to * @param name Name of the augmentation value * @param augmentable Augmentable object to - * @throws NullPointerException if any argument is null + * @throws NullPointerException if any argument is {@code null} */ public static void appendAugmentations(final ToStringHelper helper, final String name, final Augmentable augmentable) { @@ -145,7 +155,7 @@ public final class CodeHelpers { * * @param patterns Patterns to compile * @return Compiled patterns in an array - * @throws NullPointerException if the list or any of its elements is null + * @throws NullPointerException if the list or any of its elements is {@code null} * @throws VerifyException if the list has fewer than two elements */ public static Pattern @NonNull[] compilePatterns(final @NonNull List patterns) { @@ -166,7 +176,7 @@ public final class CodeHelpers { * @param pattern Enforcement pattern * @param regex Source regular expression, as defined in YANG model * @throws IllegalArgumentException if the value does not match the pattern - * @throws NullPointerException if any of the arguments are null + * @throws NullPointerException if any of the arguments is {@code null} */ public static void checkPattern(final String value, final Pattern pattern, final String regex) { if (!pattern.matcher(value).matches()) { @@ -185,7 +195,7 @@ public final class CodeHelpers { * @param patterns Enforcement patterns * @param regexes Source regular expression, as defined in YANG model. Size and order must match patterns. * @throws IllegalArgumentException if the value does not match the pattern - * @throws NullPointerException if any of the arguments are null + * @throws NullPointerException if any of the arguments is {@code null} * @throws VerifyException if the size of patterns and regexes does not match */ public static void checkPattern(final String value, final Pattern[] patterns, final String[] regexes) { @@ -214,8 +224,7 @@ public final class CodeHelpers { * @throws IllegalArgumentException always */ public static void throwInvalidLength(final String expected, final byte[] actual) { - // FIXME: MDSAL-692: use hex-encoding instead - throwInvalidLength(expected, Arrays.toString(actual)); + throwInvalidLength(expected, HexFormat.of().formatHex(actual)); } /** @@ -277,11 +286,11 @@ public final class CodeHelpers { } /** - * Check whether specified List is null and if so return an immutable list instead. This method supports + * Check whether specified List is {@code null} and if so return an immutable list instead. This method supports * non-null default getter methods. * * @param list element type - * @param input input list, may be null + * @param input input list, may be {@code null} * @return Input list or an empty list. */ public static @NonNull List nonnull(final @Nullable List input) { @@ -289,12 +298,12 @@ public final class CodeHelpers { } /** - * Check whether specified Map is null and if so return an immutable map instead. This method supports + * Check whether specified Map is {@code null} and if so return an immutable map instead. This method supports * non-null default getter methods. * * @param key type * @param value type - * @param input input map, may be null + * @param input input map, may be {@code null} * @return Input map or an empty map. */ public static @NonNull Map nonnull(final @Nullable Map input) { @@ -302,34 +311,34 @@ public final class CodeHelpers { } /** - * Check whether specified List is empty and if so return null, otherwise return input list. This method supports - * Builder/implementation list handover. + * Check whether specified List is empty and if so return {@code null}, otherwise return input list. This method + * supports Builder/implementation list handover. * * @param list element type - * @param input input list, may be null - * @return Input list or null. + * @param input input list, may be {@code null} + * @return Input list or {@code null}. */ public static @Nullable List emptyToNull(final @Nullable List input) { return input != null && input.isEmpty() ? null : input; } /** - * Check whether specified Map is empty and if so return null, otherwise return input map. This method supports - * Builder/implementation list handover. + * Check whether specified Map is empty and if so return {@code null}, otherwise return input map. This method + * supports Builder/implementation list handover. * * @param key type * @param value type - * @param input input map, may be null - * @return Input map or null. + * @param input input map, may be {@code null} + * @return Input map or {@code null}. */ public static @Nullable Map emptyToNull(final @Nullable Map input) { return input != null && input.isEmpty() ? null : input; } /** - * Return hash code of a single-property wrapper class. Since the wrapper is not null, we really want to discern - * this object being present, hence {@link Objects#hashCode()} is not really useful we would end up with {@code 0} - * for both non-present and present-with-null objects. + * Return hash code of a single-property wrapper class. Since the wrapper is not {@code null}, we really want to + * discern this object being present, hence {@link Objects#hashCode()} is not really useful we would end up with + * {@code 0} for both non-present and present-with-null objects. * * @param obj Internal object to hash * @return Wrapper object hash code @@ -339,9 +348,9 @@ public final class CodeHelpers { } /** - * Return hash code of a single-property wrapper class. Since the wrapper is not null, we really want to discern - * this object being present, hence {@link Arrays#hashCode()} is not really useful we would end up with {@code 0} - * for both non-present and present-with-null objects. + * Return hash code of a single-property wrapper class. Since the wrapper is not {@code null}, we really want to + * discern this object being present, hence {@link Arrays#hashCode()} is not really useful we would end up with + * {@code 0} for both non-present and present-with-null objects. * * @param obj Internal object to hash * @return Wrapper object hash code @@ -360,7 +369,7 @@ public final class CodeHelpers { * return result; * * - * when hashCode is returned as 0, such as due to obj being null or its hashCode being 0. + * when hashCode is returned as 0, such as due to obj being {@code null} or its hashCode being 0. * * @param hash Wrapped object hash * @return Wrapper object hash @@ -370,16 +379,48 @@ public final class CodeHelpers { } /** - * Utility method for checking whether a target object is a compatible DataObject. + * Check that the specified {@link EnumTypeObject} object is not {@code null}. This method is meant to be used with + * {@code ofName(String)} and {@code ofValue(int)} static factory methods. + * + * @param obj enumeration object, possibly {@code null} + * @param name User-supplied enumeration name + * @return Enumeration object + * @throws IllegalArgumentException if {@code obj} is {@code null} + */ + public static @NonNull T checkEnum(final @Nullable T obj, final String name) { + if (obj == null) { + throw new IllegalArgumentException("\"" + name + "\" is not a valid name"); + } + return obj; + } + + /** + * Check that the specified {@link EnumTypeObject} object is not {@code null}. This method is meant to be used with + * {@code ofName(String)} and {@code ofValue(int)} static factory methods. + * + * @param obj enumeration object, possibly {@code null} + * @param value User-supplied enumeration value + * @return Enumeration object + * @throws IllegalArgumentException if {@code obj} is {@code null} + */ + public static @NonNull T checkEnum(final @Nullable T obj, final int value) { + if (obj == null) { + throw new IllegalArgumentException(value + " is not a valid value"); + } + return obj; + } + + /** + * Utility method for checking whether a target object is a compatible {@link BindingContract}. * - * @param requiredClass Required DataObject class - * @param obj Object to check, may be null - * @return Object cast to required class, if its implemented class matches requirement, null otherwise - * @throws NullPointerException if {@code requiredClass} is null + * @param requiredClass Required BindingContract class + * @param obj Object to check, may be {@code null} + * @return Object cast to required class, if its implemented class matches requirement, {@code null} otherwise + * @throws NullPointerException if {@code requiredClass} is {@code null} */ - public static @Nullable T checkCast(final @NonNull Class requiredClass, + public static > @Nullable T checkCast(final @NonNull Class requiredClass, final @Nullable Object obj) { - return obj instanceof DataObject && requiredClass.equals(((DataObject) obj).implementedInterface()) + return obj instanceof BindingContract contract && requiredClass.equals(contract.implementedInterface()) ? requiredClass.cast(obj) : null; } @@ -388,10 +429,10 @@ public final class CodeHelpers { * * @param requiredClass Required class * @param fieldName name of the field being filled - * @param obj Object to check, may be null - * @return Object cast to required class, if its class matches requirement, or null + * @param obj Object to check, may be {@code null} + * @return Object cast to required class, if its class matches requirement, or {@code null} * @throws IllegalArgumentException if {@code obj} is not an instance of {@code requiredClass} - * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is null + * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is {@code null} */ public static @Nullable T checkFieldCast(final @NonNull Class requiredClass, final @NonNull String fieldName, final @Nullable Object obj) { @@ -410,12 +451,12 @@ public final class CodeHelpers { * @param list List, which items should be checked * @return Type-checked List * @throws IllegalArgumentException if a list item is not instance of {@code requiredClass} - * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is null + * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is {@code null} */ @SuppressWarnings("unchecked") - public static @Nullable List checkListFieldCast(final @NonNull Class requiredClass, + public static @Nullable List checkListFieldCast(final @NonNull Class requiredClass, final @NonNull String fieldName, final @Nullable List list) { - checkCollectionField(requiredClass, fieldName, list); + DoNotLeakSpotbugs.checkCollectionField(requiredClass, fieldName, list); return (List) list; } @@ -427,26 +468,12 @@ public final class CodeHelpers { * @param set Set, which items should be checked * @return Type-checked Set * @throws IllegalArgumentException if a set item is not instance of {@code requiredItemClass} - * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is null + * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is {@code null} */ @SuppressWarnings("unchecked") - public static @Nullable Set checkSetFieldCast(final @NonNull Class requiredClass, + public static @Nullable Set checkSetFieldCast(final @NonNull Class requiredClass, final @NonNull String fieldName, final @Nullable Set set) { - checkCollectionField(requiredClass, fieldName, set); + DoNotLeakSpotbugs.checkCollectionField(requiredClass, fieldName, set); return (Set) set; } - - @SuppressFBWarnings(value = "DCN_NULLPOINTER_EXCEPTION", - justification = "Internal NPE->IAE conversion") - private static void checkCollectionField(final @NonNull Class requiredClass, - final @NonNull String fieldName, final @Nullable Collection collection) { - if (collection != null) { - try { - collection.forEach(item -> requiredClass.cast(requireNonNull(item))); - } catch (ClassCastException | NullPointerException e) { - throw new IllegalArgumentException("Invalid input item for property \"" + requireNonNull(fieldName) - + "\"", e); - } - } - } }