• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / guice / #1210

04 Nov 2023 08:23PM CUT coverage: 80.045%. Remained the same
#1210

Pull #633

github

web-flow
Merge 9d1860fb9 into 408340d1e
Pull Request #633: [pom] Sortpom

1408 of 1759 relevant lines covered (80.05%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

4.49
/src/main/java/org/mybatis/guice/Preconditions.java
1
/*
2
 *    Copyright 2009-2022 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.mybatis.guice;
17

18
import java.util.Collection;
19
import java.util.NoSuchElementException;
20

21
/**
22
 * Simple static methods to be called at the start of your own methods to verify correct arguments and state. This
23
 * allows constructs such as
24
 *
25
 * <pre>
26
 * if (count <= 0) {
27
 *   throw new IllegalArgumentException("must be positive: " + count);
28
 * }
29
 * </pre>
30
 * <p>
31
 * to be replaced with the more compact
32
 * </p>
33
 *
34
 * <pre>
35
 * checkArgument(count > 0, "must be positive: %s", count);
36
 * </pre>
37
 * <p>
38
 * Note that the sense of the expression is inverted; with {@code Preconditions} you declare what you expect to be
39
 * <i>true</i>, just as you do with an <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html">
40
 * {@code assert}</a> or a JUnit {@code assertTrue()} call.
41
 * </p>
42
 * <p>
43
 * Take care not to confuse precondition checking with other similar types of checks! Precondition exceptions --
44
 * including those provided here, but also {@link IndexOutOfBoundsException}, {@link NoSuchElementException},
45
 * {@link UnsupportedOperationException} and others -- are used to signal that the <i>calling method</i> has made an
46
 * error. This tells the caller that it should not have invoked the method when it did, with the arguments it did, or
47
 * perhaps <i>ever</i>. Postcondition or other invariant failures should not throw these types of exceptions.
48
 * </p>
49
 * <p>
50
 * <b>Note:</b> The methods of the {@code Preconditions} class are highly unusual in one way: they are <i>supposed
51
 * to</i> throw exceptions, and promise in their specifications to do so even when given perfectly valid input. That is,
52
 * {@code null} is a valid parameter to the method {@link #checkNotNull(Object)} -- and technically this parameter could
53
 * be even marked as {@link com.google.inject.internal.util.Nullable} -- yet the method will still throw an exception
54
 * anyway, because that's what its contract says to do.
55
 * </p>
56
 * <p>
57
 * This class may be used with the Google Web Toolkit (GWT).
58
 * </p>
59
 *
60
 * @author Kevin Bourrillion
61
 */
62
final class Preconditions {
63
  private Preconditions() {
64
  }
65

66
  /**
67
   * Ensures the truth of an expression involving one or more parameters to the calling method.
68
   *
69
   * @param expression
70
   *          a boolean expression
71
   *
72
   * @throws IllegalArgumentException
73
   *           if {@code expression} is false
74
   */
75
  public static void checkArgument(boolean expression) {
76
    if (!expression) {
×
77
      throw new IllegalArgumentException();
×
78
    }
79
  }
×
80

81
  /**
82
   * Ensures the truth of an expression involving one or more parameters to the calling method.
83
   *
84
   * @param expression
85
   *          a boolean expression
86
   * @param errorMessage
87
   *          the exception message to use if the check fails; will be converted to a string using
88
   *          {@link String#valueOf(Object)}
89
   *
90
   * @throws IllegalArgumentException
91
   *           if {@code expression} is false
92
   */
93
  public static void checkArgument(boolean expression, Object errorMessage) {
94
    if (!expression) {
1✔
95
      throw new IllegalArgumentException(String.valueOf(errorMessage));
×
96
    }
97
  }
1✔
98

99
  /**
100
   * Ensures the truth of an expression involving one or more parameters to the calling method.
101
   *
102
   * @param expression
103
   *          a boolean expression
104
   * @param errorMessageTemplate
105
   *          a template for the exception message should the check fail. The message is formed by replacing each
106
   *          {@code %s} placeholder in the template with an argument. These are matched by position - the first
107
   *          {@code %s} gets {@code errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted
108
   *          message in square braces. Unmatched placeholders will be left as-is.
109
   * @param errorMessageArgs
110
   *          the arguments to be substituted into the message template. Arguments are converted to strings using
111
   *          {@link String#valueOf(Object)}.
112
   *
113
   * @throws IllegalArgumentException
114
   *           if {@code expression} is false
115
   * @throws NullPointerException
116
   *           if the check fails and either {@code
117
   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let this happen)
118
   */
119
  public static void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
120
    if (!expression) {
1✔
121
      throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
×
122
    }
123
  }
1✔
124

125
  /**
126
   * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to
127
   * the calling method.
128
   *
129
   * @param expression
130
   *          a boolean expression
131
   *
132
   * @throws IllegalStateException
133
   *           if {@code expression} is false
134
   */
135
  public static void checkState(boolean expression) {
136
    if (!expression) {
×
137
      throw new IllegalStateException();
×
138
    }
139
  }
×
140

141
  /**
142
   * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to
143
   * the calling method.
144
   *
145
   * @param expression
146
   *          a boolean expression
147
   * @param errorMessage
148
   *          the exception message to use if the check fails; will be converted to a string using
149
   *          {@link String#valueOf(Object)}
150
   *
151
   * @throws IllegalStateException
152
   *           if {@code expression} is false
153
   */
154
  public static void checkState(boolean expression, Object errorMessage) {
155
    if (!expression) {
×
156
      throw new IllegalStateException(String.valueOf(errorMessage));
×
157
    }
158
  }
×
159

160
  /**
161
   * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to
162
   * the calling method.
163
   *
164
   * @param expression
165
   *          a boolean expression
166
   * @param errorMessageTemplate
167
   *          a template for the exception message should the check fail. The message is formed by replacing each
168
   *          {@code %s} placeholder in the template with an argument. These are matched by position - the first
169
   *          {@code %s} gets {@code errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted
170
   *          message in square braces. Unmatched placeholders will be left as-is.
171
   * @param errorMessageArgs
172
   *          the arguments to be substituted into the message template. Arguments are converted to strings using
173
   *          {@link String#valueOf(Object)}.
174
   *
175
   * @throws IllegalStateException
176
   *           if {@code expression} is false
177
   * @throws NullPointerException
178
   *           if the check fails and either {@code
179
   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let this happen)
180
   */
181
  public static void checkState(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
182
    if (!expression) {
×
183
      throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs));
×
184
    }
185
  }
×
186

187
  /**
188
   * Ensures that an object reference passed as a parameter to the calling method is not null.
189
   *
190
   * @param reference
191
   *          an object reference
192
   *
193
   * @return the non-null reference that was validated
194
   *
195
   * @throws NullPointerException
196
   *           if {@code reference} is null
197
   */
198
  public static <T> T checkNotNull(T reference) {
199
    if (reference == null) {
×
200
      throw new NullPointerException();
×
201
    }
202
    return reference;
×
203
  }
204

205
  /**
206
   * Ensures that an object reference passed as a parameter to the calling method is not null.
207
   *
208
   * @param reference
209
   *          an object reference
210
   * @param errorMessage
211
   *          the exception message to use if the check fails; will be converted to a string using
212
   *          {@link String#valueOf(Object)}
213
   *
214
   * @return the non-null reference that was validated
215
   *
216
   * @throws NullPointerException
217
   *           if {@code reference} is null
218
   */
219
  public static <T> T checkNotNull(T reference, Object errorMessage) {
220
    if (reference == null) {
×
221
      throw new NullPointerException(String.valueOf(errorMessage));
×
222
    }
223
    return reference;
×
224
  }
225

226
  /**
227
   * Ensures that an object reference passed as a parameter to the calling method is not null.
228
   *
229
   * @param reference
230
   *          an object reference
231
   * @param errorMessageTemplate
232
   *          a template for the exception message should the check fail. The message is formed by replacing each
233
   *          {@code %s} placeholder in the template with an argument. These are matched by position - the first
234
   *          {@code %s} gets {@code errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted
235
   *          message in square braces. Unmatched placeholders will be left as-is.
236
   * @param errorMessageArgs
237
   *          the arguments to be substituted into the message template. Arguments are converted to strings using
238
   *          {@link String#valueOf(Object)}.
239
   *
240
   * @return the non-null reference that was validated
241
   *
242
   * @throws NullPointerException
243
   *           if {@code reference} is null
244
   */
245
  public static <T> T checkNotNull(T reference, String errorMessageTemplate, Object... errorMessageArgs) {
246
    if (reference == null) {
×
247
      // If either of these parameters is null, the right thing happens anyway
248
      throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs));
×
249
    }
250
    return reference;
×
251
  }
252

253
  /**
254
   * Ensures that an {@code Iterable} object passed as a parameter to the calling method is not null and contains no
255
   * null elements.
256
   *
257
   * @param iterable
258
   *          the iterable to check the contents of
259
   *
260
   * @return the non-null {@code iterable} reference just validated
261
   *
262
   * @throws NullPointerException
263
   *           if {@code iterable} is null or contains at least one null element
264
   */
265
  public static <T extends Iterable<?>> T checkContentsNotNull(T iterable) {
266
    if (containsOrIsNull(iterable)) {
×
267
      throw new NullPointerException();
×
268
    }
269
    return iterable;
×
270
  }
271

272
  /**
273
   * Ensures that an {@code Iterable} object passed as a parameter to the calling method is not null and contains no
274
   * null elements.
275
   *
276
   * @param iterable
277
   *          the iterable to check the contents of
278
   * @param errorMessage
279
   *          the exception message to use if the check fails; will be converted to a string using
280
   *          {@link String#valueOf(Object)}
281
   *
282
   * @return the non-null {@code iterable} reference just validated
283
   *
284
   * @throws NullPointerException
285
   *           if {@code iterable} is null or contains at least one null element
286
   */
287
  public static <T extends Iterable<?>> T checkContentsNotNull(T iterable, Object errorMessage) {
288
    if (containsOrIsNull(iterable)) {
×
289
      throw new NullPointerException(String.valueOf(errorMessage));
×
290
    }
291
    return iterable;
×
292
  }
293

294
  /**
295
   * Ensures that an {@code Iterable} object passed as a parameter to the calling method is not null and contains no
296
   * null elements.
297
   *
298
   * @param iterable
299
   *          the iterable to check the contents of
300
   * @param errorMessageTemplate
301
   *          a template for the exception message should the check fail. The message is formed by replacing each
302
   *          {@code %s} placeholder in the template with an argument. These are matched by position - the first
303
   *          {@code %s} gets {@code errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted
304
   *          message in square braces. Unmatched placeholders will be left as-is.
305
   * @param errorMessageArgs
306
   *          the arguments to be substituted into the message template. Arguments are converted to strings using
307
   *          {@link String#valueOf(Object)}.
308
   *
309
   * @return the non-null {@code iterable} reference just validated
310
   *
311
   * @throws NullPointerException
312
   *           if {@code iterable} is null or contains at least one null element
313
   */
314
  public static <T extends Iterable<?>> T checkContentsNotNull(T iterable, String errorMessageTemplate,
315
      Object... errorMessageArgs) {
316
    if (containsOrIsNull(iterable)) {
×
317
      throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs));
×
318
    }
319
    return iterable;
×
320
  }
321

322
  private static boolean containsOrIsNull(Iterable<?> iterable) {
323
    if (iterable == null) {
×
324
      return true;
×
325
    }
326

327
    if (iterable instanceof Collection) {
×
328
      Collection<?> collection = (Collection<?>) iterable;
×
329
      try {
330
        return collection.contains(null);
×
331
      } catch (NullPointerException e) {
×
332
        // A NPE implies that the collection doesn't contain null.
333
        return false;
×
334
      }
335
    } else {
336
      for (Object element : iterable) {
×
337
        if (element == null) {
×
338
          return true;
×
339
        }
340
      }
×
341
      return false;
×
342
    }
343
  }
344

345
  /**
346
   * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size {@code size}. An
347
   * element index may range from zero, inclusive, to {@code size}, exclusive.
348
   *
349
   * @param index
350
   *          a user-supplied index identifying an element of an array, list or string
351
   * @param size
352
   *          the size of that array, list or string
353
   *
354
   * @throws IndexOutOfBoundsException
355
   *           if {@code index} is negative or is not less than {@code size}
356
   * @throws IllegalArgumentException
357
   *           if {@code size} is negative
358
   */
359
  public static void checkElementIndex(int index, int size) {
360
    checkElementIndex(index, size, "index");
×
361
  }
×
362

363
  /**
364
   * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size {@code size}. An
365
   * element index may range from zero, inclusive, to {@code size}, exclusive.
366
   *
367
   * @param index
368
   *          a user-supplied index identifying an element of an array, list or string
369
   * @param size
370
   *          the size of that array, list or string
371
   * @param desc
372
   *          the text to use to describe this index in an error message
373
   *
374
   * @throws IndexOutOfBoundsException
375
   *           if {@code index} is negative or is not less than {@code size}
376
   * @throws IllegalArgumentException
377
   *           if {@code size} is negative
378
   */
379
  public static void checkElementIndex(int index, int size, String desc) {
380
    checkArgument(size >= 0, "negative size: %s", size);
×
381
    if (index < 0) {
×
382
      throw new IndexOutOfBoundsException(format("%s (%s) must not be negative", desc, index));
×
383
    }
384
    if (index >= size) {
×
385
      throw new IndexOutOfBoundsException(format("%s (%s) must be less than size (%s)", desc, index, size));
×
386
    }
387
  }
×
388

389
  /**
390
   * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of size {@code size}. A
391
   * position index may range from zero to {@code size}, inclusive.
392
   *
393
   * @param index
394
   *          a user-supplied index identifying a position in an array, list or string
395
   * @param size
396
   *          the size of that array, list or string
397
   *
398
   * @throws IndexOutOfBoundsException
399
   *           if {@code index} is negative or is greater than {@code size}
400
   * @throws IllegalArgumentException
401
   *           if {@code size} is negative
402
   */
403
  public static void checkPositionIndex(int index, int size) {
404
    checkPositionIndex(index, size, "index");
×
405
  }
×
406

407
  /**
408
   * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of size {@code size}. A
409
   * position index may range from zero to {@code size}, inclusive.
410
   *
411
   * @param index
412
   *          a user-supplied index identifying a position in an array, list or string
413
   * @param size
414
   *          the size of that array, list or string
415
   * @param desc
416
   *          the text to use to describe this index in an error message
417
   *
418
   * @throws IndexOutOfBoundsException
419
   *           if {@code index} is negative or is greater than {@code size}
420
   * @throws IllegalArgumentException
421
   *           if {@code size} is negative
422
   */
423
  public static void checkPositionIndex(int index, int size, String desc) {
424
    checkArgument(size >= 0, "negative size: %s", size);
×
425
    if (index < 0) {
×
426
      throw new IndexOutOfBoundsException(format("%s (%s) must not be negative", desc, index));
×
427
    }
428
    if (index > size) {
×
429
      throw new IndexOutOfBoundsException(format("%s (%s) must not be greater than size (%s)", desc, index, size));
×
430
    }
431
  }
×
432

433
  /**
434
   * Ensures that {@code start} and {@code end} specify a valid <i>positions</i> in an array, list or string of size
435
   * {@code size}, and are in order. A position index may range from zero to {@code size}, inclusive.
436
   *
437
   * @param start
438
   *          a user-supplied index identifying a starting position in an array, list or string
439
   * @param end
440
   *          a user-supplied index identifying a ending position in an array, list or string
441
   * @param size
442
   *          the size of that array, list or string
443
   *
444
   * @throws IndexOutOfBoundsException
445
   *           if either index is negative or is greater than {@code size}, or if {@code end} is less than {@code start}
446
   * @throws IllegalArgumentException
447
   *           if {@code size} is negative
448
   */
449
  public static void checkPositionIndexes(int start, int end, int size) {
450
    checkPositionIndex(start, size, "start index");
×
451
    checkPositionIndex(end, size, "end index");
×
452
    if (end < start) {
×
453
      throw new IndexOutOfBoundsException(format("end index (%s) must not be less than start index (%s)", end, start));
×
454
    }
455
  }
×
456

457
  /**
458
   * Substitutes each {@code %s} in {@code template} with an argument. These are matched by position - the first
459
   * {@code %s} gets {@code args[0]}, etc. If there are more arguments than placeholders, the unmatched arguments will
460
   * be appended to the end of the formatted message in square braces.
461
   *
462
   * @param template
463
   *          a non-null string containing 0 or more {@code %s} placeholders.
464
   * @param args
465
   *          the arguments to be substituted into the message template. Arguments are converted to strings using
466
   *          {@link String#valueOf(Object)}. Arguments can be null.
467
   */
468
  // VisibleForTesting
469
  static String format(String template, Object... args) {
470
    // start substituting the arguments into the '%s' placeholders
471
    StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
×
472
    int templateStart = 0;
×
473
    int i = 0;
×
474
    while (i < args.length) {
×
475
      int placeholderStart = template.indexOf("%s", templateStart);
×
476
      if (placeholderStart == -1) {
×
477
        break;
×
478
      }
479
      builder.append(template.substring(templateStart, placeholderStart));
×
480
      builder.append(args[i++]);
×
481
      templateStart = placeholderStart + 2;
×
482
    }
×
483
    builder.append(template.substring(templateStart));
×
484

485
    // if we run out of placeholders, append the extra args in square braces
486
    if (i < args.length) {
×
487
      builder.append(" [");
×
488
      builder.append(args[i++]);
×
489
      while (i < args.length) {
×
490
        builder.append(", ");
×
491
        builder.append(args[i++]);
×
492
      }
493
      builder.append("]");
×
494
    }
495

496
    return builder.toString();
×
497
  }
498
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc