Skip to content

Commit 31b44c5

Browse files
amahusseinjojochuang
authored andcommitted
HADOOP-17929. implement non-guava Precondition checkArgument (#3473)
Reviewed-by: Viraj Jasani <vjasani@apache.org> (cherry picked from commit 0c498f2)
1 parent 5ed4274 commit 31b44c5

File tree

2 files changed

+192
-1
lines changed

2 files changed

+192
-1
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Preconditions.java

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public final class Preconditions {
4444

4545
private static final String VALIDATE_IS_NOT_NULL_EX_MESSAGE =
4646
"The argument object is NULL";
47+
private static final String CHECK_ARGUMENT_EX_MESSAGE =
48+
"The argument expression is false";
4749

4850
private Preconditions() {
4951
}
@@ -122,7 +124,7 @@ public static <T> T checkNotNull(final T obj, final String message,
122124
}
123125

124126
/**
125-
* <p>Preconditions that the specified argument is not {@code null},
127+
* Preconditions that the specified argument is not {@code null},
126128
* throwing a NPE exception otherwise.
127129
*
128130
* <p>The message of the exception is {@code msgSupplier.get()}.</p>
@@ -156,8 +158,95 @@ public static <T> T checkNotNull(final T obj,
156158
return obj;
157159
}
158160

161+
/**
162+
* Ensures the truth of an expression involving one or more parameters to the calling method.
163+
*
164+
* @param expression a boolean expression
165+
* @throws IllegalArgumentException if {@code expression} is false
166+
*/
167+
public static void checkArgument(final boolean expression) {
168+
if (!expression) {
169+
throw new IllegalArgumentException();
170+
}
171+
}
172+
173+
/**
174+
* Ensures the truth of an expression involving one or more parameters to the calling method.
175+
*
176+
* @param expression a boolean expression
177+
* @param errorMessage the exception message to use if the check fails; will be converted to a
178+
* string using {@link String#valueOf(Object)}
179+
* @throws IllegalArgumentException if {@code expression} is false
180+
*/
181+
public static void checkArgument(final boolean expression, final Object errorMessage) {
182+
if (!expression) {
183+
throw new IllegalArgumentException(String.valueOf(errorMessage));
184+
}
185+
}
186+
187+
/**
188+
* Ensures the truth of an expression involving one or more parameters to the calling method.
189+
*
190+
* <p>The message of the exception is {@code String.format(f, m)}.</p>
191+
*
192+
* @param expression a boolean expression
193+
* @param errorMsg the {@link String#format(String, Object...)}
194+
* exception message if valid. Otherwise,
195+
* the message is {@link #CHECK_ARGUMENT_EX_MESSAGE}
196+
* @param errorMsgArgs the optional values for the formatted exception message.
197+
* @throws IllegalArgumentException if {@code expression} is false
198+
*/
199+
public static void checkArgument(
200+
final boolean expression,
201+
final String errorMsg,
202+
Object... errorMsgArgs) {
203+
if (!expression) {
204+
String msg;
205+
try {
206+
msg = String.format(errorMsg, errorMsgArgs);
207+
} catch (Exception e) {
208+
LOG.debug("Error formatting message", e);
209+
msg = CHECK_ARGUMENT_EX_MESSAGE;
210+
}
211+
throw new IllegalArgumentException(msg);
212+
}
213+
}
214+
215+
/**
216+
* Preconditions that the expression involving one or more parameters to the calling method.
217+
*
218+
* <p>The message of the exception is {@code msgSupplier.get()}.</p>
219+
*
220+
* @param expression a boolean expression
221+
* @param msgSupplier the {@link Supplier#get()} set the
222+
* exception message if valid. Otherwise,
223+
* the message is {@link #CHECK_ARGUMENT_EX_MESSAGE}
224+
* @throws IllegalArgumentException if {@code expression} is false
225+
*/
226+
public static void checkArgument(
227+
final boolean expression,
228+
final Supplier<String> msgSupplier) {
229+
if (!expression) {
230+
String msg;
231+
try {
232+
// note that we can get NPE evaluating the message itself;
233+
// but we do not want this to override the actual NPE.
234+
msg = msgSupplier.get();
235+
} catch (Exception e) {
236+
LOG.debug("Error formatting message", e);
237+
msg = CHECK_ARGUMENT_EX_MESSAGE;
238+
}
239+
throw new IllegalArgumentException(msg);
240+
}
241+
}
242+
159243
/* @VisibleForTesting */
160244
static String getDefaultNullMSG() {
161245
return VALIDATE_IS_NOT_NULL_EX_MESSAGE;
162246
}
247+
248+
/* @VisibleForTesting */
249+
static String getDefaultCheckArgumentMSG() {
250+
return CHECK_ARGUMENT_EX_MESSAGE;
251+
}
163252
}

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestPreconditions.java

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
package org.apache.hadoop.util;
2020

21+
import java.util.function.Supplier;
22+
2123
import org.junit.Test;
2224

2325
import org.apache.hadoop.test.LambdaTestUtils;
@@ -119,4 +121,104 @@ public void testCheckNotNullFailure() throws Exception {
119121
() -> Preconditions.checkNotNull(null,
120122
() -> String.format(NULL_FORMATTER, NON_NULL_STRING)));
121123
}
124+
125+
@Test
126+
public void testCheckArgumentWithSuccess() throws Exception {
127+
// success
128+
Preconditions.checkArgument(true);
129+
// null supplier
130+
Preconditions.checkArgument(true, null);
131+
// null message
132+
Preconditions.checkArgument(true, (String) null);
133+
Preconditions.checkArgument(true, NON_NULL_STRING);
134+
// null in string format
135+
Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS, null, null);
136+
// illegalformat
137+
Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS, 1, 2);
138+
// ill-formated string supplier
139+
Preconditions.checkArgument(true, ()-> String.format("%d",
140+
NON_INT_STRING));
141+
// null pattern to string formatter
142+
Preconditions.checkArgument(true, NULL_FORMATTER, null, 1);
143+
// null arguments to string formatter
144+
Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS,
145+
null, null);
146+
// illegal format exception
147+
Preconditions.checkArgument(true, "message %d %d",
148+
NON_INT_STRING, 1);
149+
// insufficient arguments
150+
Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS,
151+
NON_INT_STRING);
152+
// null format in string supplier
153+
Preconditions.checkArgument(true,
154+
() -> String.format(NULL_FORMATTER, NON_INT_STRING));
155+
}
156+
157+
@Test
158+
public void testCheckArgumentWithFailure() throws Exception {
159+
// failure without message
160+
LambdaTestUtils.intercept(IllegalArgumentException.class,
161+
() -> Preconditions.checkArgument(false));
162+
errorMessage = null;
163+
// failure with Null message
164+
LambdaTestUtils.intercept(IllegalArgumentException.class,
165+
null,
166+
() -> Preconditions.checkArgument(false, errorMessage));
167+
// failure with message
168+
errorMessage = EXPECTED_ERROR_MSG;
169+
LambdaTestUtils.intercept(IllegalArgumentException.class,
170+
errorMessage,
171+
() -> Preconditions.checkArgument(false, errorMessage));
172+
173+
// failure with message format
174+
errorMessage = EXPECTED_ERROR_MSG + " %s";
175+
String arg = "IllegalArgExcep";
176+
String expectedMSG = String.format(errorMessage, arg);
177+
LambdaTestUtils.intercept(IllegalArgumentException.class,
178+
expectedMSG,
179+
() -> Preconditions.checkArgument(false, errorMessage, arg));
180+
181+
// failure with multiple arg message format
182+
errorMessage = EXPECTED_ERROR_MSG_ARGS;
183+
expectedMSG =
184+
String.format(errorMessage, arg, 1);
185+
LambdaTestUtils.intercept(IllegalArgumentException.class,
186+
expectedMSG,
187+
() -> Preconditions.checkArgument(false, errorMessage, arg, 1));
188+
189+
// ignore illegal format will be thrown if the case is not handled correctly
190+
LambdaTestUtils.intercept(IllegalArgumentException.class,
191+
Preconditions.getDefaultCheckArgumentMSG(),
192+
() -> Preconditions.checkArgument(false,
193+
errorMessage, 1, NON_INT_STRING));
194+
195+
// ignore illegal format will be thrown for insufficient Insufficient Args
196+
LambdaTestUtils.intercept(IllegalArgumentException.class,
197+
Preconditions.getDefaultCheckArgumentMSG(),
198+
() -> Preconditions.checkArgument(false, errorMessage, NON_NULL_STRING));
199+
200+
// failure with Null supplier
201+
final Supplier<String> nullSupplier = null;
202+
LambdaTestUtils.intercept(IllegalArgumentException.class,
203+
null,
204+
() -> Preconditions.checkArgument(false, nullSupplier));
205+
206+
// ignore illegal format in supplier
207+
LambdaTestUtils.intercept(IllegalArgumentException.class,
208+
Preconditions.getDefaultCheckArgumentMSG(),
209+
() -> Preconditions.checkArgument(false,
210+
() -> String.format(errorMessage, 1, NON_INT_STRING)));
211+
212+
// ignore insufficient arguments in string Supplier
213+
LambdaTestUtils.intercept(IllegalArgumentException.class,
214+
Preconditions.getDefaultCheckArgumentMSG(),
215+
() -> Preconditions.checkArgument(false,
216+
() -> String.format(errorMessage, NON_NULL_STRING)));
217+
218+
// ignore null formatter
219+
LambdaTestUtils.intercept(IllegalArgumentException.class,
220+
Preconditions.getDefaultCheckArgumentMSG(),
221+
() -> Preconditions.checkArgument(false,
222+
() -> String.format(NULL_FORMATTER, NON_NULL_STRING)));
223+
}
122224
}

0 commit comments

Comments
 (0)