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=1a1870efc44bbe69f0a2bcbd08b98c76bdefba2f;hb=99dd61f2037307d1b59f72a47e89d845f138acde;hp=b378a703ba86e688acb52e01afef817f51d5b333;hpb=314a6573772c8593feecb69210357b193184e3be;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 b378a703ba..1a1870efc4 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 @@ -16,7 +16,7 @@ import com.google.common.base.VerifyException; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.Arrays; -import java.util.Collection; +import java.util.HexFormat; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -30,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() { @@ -51,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) { @@ -72,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) { @@ -85,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) { @@ -107,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) { @@ -144,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) { @@ -165,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()) { @@ -184,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) { @@ -213,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)); } /** @@ -276,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) { @@ -288,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) { @@ -301,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 @@ -338,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 @@ -350,16 +360,67 @@ public final class CodeHelpers { } /** - * Utility method for checking whether a target object is a compatible DataObject. + * The constant '31' is the result of folding this code: + *
+     *   
+     *     final int prime = 31;
+     *     int result = 1;
+     *     result = result * prime + Objects.hashCode(obj);
+     *     return result;
+     *   
+     * 
+ * when hashCode is returned as 0, such as due to obj being {@code null} or its hashCode being 0. * - * @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 hash Wrapped object hash + * @return Wrapper object hash */ - public static @Nullable T checkCast(final @NonNull Class requiredClass, + private static int wrapHashCode(final int hash) { + return hash == 0 ? 31 : hash; + } + + /** + * 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 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, 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; } @@ -368,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) { @@ -389,61 +450,30 @@ public final class CodeHelpers { * @param fieldName name of the field being filled * @param list List, which items should be checked * @return Type-checked List - * @throws IllegalArgumentException if a list item is not instance of {@code requiredItemClass} - * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is null + * @throws IllegalArgumentException if a list item is not instance of {@code requiredClass} + * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is {@code null} */ @SuppressWarnings("unchecked") 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; } /** - * Utility method for checking whether the items of target list is compatible. + * Utility method for checking whether the items of target set is compatible. * * @param requiredClass Required item class * @param fieldName name of the field being filled * @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, final @NonNull String fieldName, final @Nullable Set set) { - checkCollectionField(requiredClass, fieldName, set); + DoNotLeakSpotbugs.checkCollectionField(requiredClass, fieldName, set); return (Set) set; } - - 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 list item for property \"" + requireNonNull(fieldName) - + "\"", e); - } - } - } - - /** - * The constant '31' is the result of folding this code: - *
-     *   
-     *     final int prime = 31;
-     *     int result = 1;
-     *     result = result * prime + Objects.hashCode(obj);
-     *     return result;
-     *   
-     * 
- * when hashCode is returned as 0, such as due to obj being null or its hashCode being 0. - * - * @param hash Wrapped object hash - * @return Wrapper object hash - */ - private static int wrapHashCode(final int hash) { - return hash == 0 ? 31 : hash; - } }