1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.lang3.function;
19
20 import java.util.function.Supplier;
21
22 import javax.annotation.Nonnull;
23 import javax.annotation.Nullable;
24
25 import org.apache.commons.lang3.ObjectUtils;
26
27 /**
28 * This class provides some replacements for the corresponding methods in
29 * {@link java.util.Objects}. The replacements have the advantage, that they are properly
30 * annotated with {@link Nullable}, and/or {@link Nonnull}, so they let the
31 * compiler know what their respective results are.
32 *
33 * The various {@code requireNonNull} methods are particularly handy, when
34 * dealing with external code, that a) doesn't support the {@link Nonnull}
35 * annotation, or if you know for other reasons, that an object is non-null.
36 * Take for example, a {@link java.util.Map map}, that you have filled with
37 * non-null values. So, in your opinion, the following should be perfectly
38 * valid code:
39 * <pre>
40 * final Map<String,Object> map = getMapOfNonNullValues();
41 * final @Nonnull Object o = map.get("SomeKey");
42 * </pre>
43 * However, if your Java compiler *does* null analysis, it will reject this
44 * example as invalid, because {@link java.util.Map#get(Object)} might return
45 * a null value. As a workaround, you can use this:
46 * <pre>
47 * import static org.apache.commons.lang3.function.Objects.requireNonNull;
48 *
49 * final Map<String,Object> map = getMapOfNonNullValues();
50 * final @Nonnull Object o = requireNonNull(map.get("SomeKey"));
51 * </pre>
52 *
53 * This class is somewhat redundant with regards to {@link ObjectUtils}.
54 * For example, {@link #requireNonNull(Object, Object)} is almost equivalent
55 * with {@link ObjectUtils#getIfNull(Object, Object)}. However, it isn't
56 * quite the same, because the latter can, in fact, return null. The former
57 * can't, and the Java compiler confirms this.(An alternative to redundancy
58 * would have been to change the {@code ObjectUtils} class. However, that
59 * would mean loosing upwards compatibility, and we don't do that.)
60 *
61 * @since 3.12.0
62 */
63 public class Objects {
64
65 /**
66 * Checks, whether the given object is non-null. If so, returns the non-null
67 * object as a result value. Otherwise, a NullPointerException is thrown.
68 * @param <T> The type of parameter {@code value}, also the result type.
69 * @param value The value, which is being checked.
70 * @return The given input value, if it was found to be non-null.
71 * @throws NullPointerException The input value was null.
72 * @see java.util.Objects#requireNonNull(Object)
73 */
74 public static <T> @Nonnull T requireNonNull(@Nullable final T value) throws NullPointerException {
75 return requireNonNull(value, "The value must not be null.");
76 }
77
78 /**
79 * Checks, whether the given object is non-null. If so, returns the non-null
80 * object as a result value. Otherwise, invokes the given {@link Supplier},
81 * and returns the suppliers result value.
82 * @param <T> The type of parameter {@code value}, also the result type of
83 * the default value supplier, and of the method itself.
84 * @param <E> The type of exception, that the {@code default value supplier},
85 * may throw.
86 * @param value The value, which is being checked.
87 * @param defaultValueSupplier The supplier, which returns the default value. This default
88 * value <em>must</em> be non-null. The supplier will only be invoked, if
89 * necessary. (If the {@code value} parameter is null, that is.)
90 * @return The given input value, if it was found to be non-null. Otherwise,
91 * the value, that has been returned by the default value supplier.
92 * @see #requireNonNull(Object)
93 * @see #requireNonNull(Object, String)
94 * @see #requireNonNull(Object, Supplier)
95 * @throws NullPointerException The default value supplier is null, or the default
96 * value supplier has returned null.
97 */
98 public static <T, E extends Throwable> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final FailableSupplier<T, E> defaultValueSupplier) throws NullPointerException {
99 if (value == null) {
100 final FailableSupplier<T, ?> supplier = requireNonNull(defaultValueSupplier, "The supplier must not be null");
101 final T defaultValue;
102 try {
103 defaultValue = supplier.get();
104 } catch (final Throwable t) {
105 throw Failable.rethrow(t);
106 }
107 return requireNonNull(defaultValue, "The supplier must not return null.");
108 }
109 return value;
110 }
111
112 /**
113 * Checks, whether the given object is non-null. If so, returns the non-null
114 * object as a result value. Otherwise, a NullPointerException is thrown.
115 * @param <T> The type of parameter {@code value}, also the result type.
116 * @param value The value, which is being checked.
117 * @param msg A string, which is being used as the exceptions message, if the
118 * check fails.
119 * @return The given input value, if it was found to be non-null.
120 * @throws NullPointerException The input value was null.
121 * @see java.util.Objects#requireNonNull(Object, String)
122 * @see #requireNonNull(Object, Supplier)
123 */
124 public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final String msg) throws NullPointerException {
125 if (value == null) {
126 throw new NullPointerException(msg);
127 }
128 return value;
129 }
130
131 /**
132 * Checks, whether the given object is non-null. If so, returns the non-null
133 * object as a result value. Otherwise, a NullPointerException is thrown.
134 * @param <T> The type of parameter {@code value}, also the result type.
135 * @param value The value, which is being checked.
136 * @param msgSupplier A supplier, which creates the exception message, if the check fails.
137 * This supplier will only be invoked, if necessary.
138 * @return The given input value, if it was found to be non-null.
139 * @throws NullPointerException The input value was null.
140 * @see java.util.Objects#requireNonNull(Object, String)
141 * @see #requireNonNull(Object, String)
142 */
143 public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final Supplier<String> msgSupplier) throws NullPointerException {
144 if (value == null) {
145 throw new NullPointerException(msgSupplier.get());
146 }
147 return value;
148 }
149
150 /**
151 * Checks, whether the given object is non-null. If so, returns the non-null
152 * object as a result value. Otherwise, a NullPointerException is thrown.
153 * @param <T> The type of parameter {@code value}, also the result type.
154 * @param value The value, which is being checked.
155 * @param defaultValue The default value, which is being returned, if the
156 * check fails, and the {@code value} is null.
157 * @throws NullPointerException The input value, and the default value are null.
158 * @return The given input value, if it was found to be non-null.
159 * @see java.util.Objects#requireNonNull(Object)
160 */
161 public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final T defaultValue) throws NullPointerException {
162 return value == null ? requireNonNull(defaultValue) : value;
163 }
164 }