1 /*
2 * Copyright (C) 2014 jsonwebtoken.io
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 * http://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 io.jsonwebtoken.lang;
17
18 import java.io.Closeable;
19 import java.io.IOException;
20 import java.lang.reflect.Array;
21 import java.util.Arrays;
22
23 public final class Objects {
24
25 //for code coverage
26 private static final Objects INSTANCE = new Objects();
27
28 private Objects(){}
29
30 private static final int INITIAL_HASH = 7;
31 private static final int MULTIPLIER = 31;
32
33 private static final String EMPTY_STRING = "";
34 private static final String NULL_STRING = "null";
35 private static final String ARRAY_START = "{";
36 private static final String ARRAY_END = "}";
37 private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
38 private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
39
40 /**
41 * Return whether the given throwable is a checked exception:
42 * that is, neither a RuntimeException nor an Error.
43 *
44 * @param ex the throwable to check
45 * @return whether the throwable is a checked exception
46 * @see java.lang.Exception
47 * @see java.lang.RuntimeException
48 * @see java.lang.Error
49 */
50 public static boolean isCheckedException(Throwable ex) {
51 return !(ex instanceof RuntimeException || ex instanceof Error);
52 }
53
54 /**
55 * Check whether the given exception is compatible with the exceptions
56 * declared in a throws clause.
57 *
58 * @param ex the exception to checked
59 * @param declaredExceptions the exceptions declared in the throws clause
60 * @return whether the given exception is compatible
61 */
62 public static boolean isCompatibleWithThrowsClause(Throwable ex, Class[] declaredExceptions) {
63 if (!isCheckedException(ex)) {
64 return true;
65 }
66 if (declaredExceptions != null) {
67 int i = 0;
68 while (i < declaredExceptions.length) {
69 if (declaredExceptions[i].isAssignableFrom(ex.getClass())) {
70 return true;
71 }
72 i++;
73 }
74 }
75 return false;
76 }
77
78 /**
79 * Determine whether the given object is an array:
80 * either an Object array or a primitive array.
81 *
82 * @param obj the object to check
83 */
84 public static boolean isArray(Object obj) {
85 return (obj != null && obj.getClass().isArray());
86 }
87
88 /**
89 * Determine whether the given array is empty:
90 * i.e. <code>null</code> or of zero length.
91 *
92 * @param array the array to check
93 */
94 public static boolean isEmpty(Object[] array) {
95 return (array == null || array.length == 0);
96 }
97
98 /**
99 * Returns {@code true} if the specified byte array is null or of zero length, {@code false} otherwise.
100 *
101 * @param array the byte array to check
102 * @return {@code true} if the specified byte array is null or of zero length, {@code false} otherwise.
103 */
104 public static boolean isEmpty(byte[] array) {
105 return array == null || array.length == 0;
106 }
107
108 /**
109 * Check whether the given array contains the given element.
110 *
111 * @param array the array to check (may be <code>null</code>,
112 * in which case the return value will always be <code>false</code>)
113 * @param element the element to check for
114 * @return whether the element has been found in the given array
115 */
116 public static boolean containsElement(Object[] array, Object element) {
117 if (array == null) {
118 return false;
119 }
120 for (Object arrayEle : array) {
121 if (nullSafeEquals(arrayEle, element)) {
122 return true;
123 }
124 }
125 return false;
126 }
127
128 /**
129 * Check whether the given array of enum constants contains a constant with the given name,
130 * ignoring case when determining a match.
131 *
132 * @param enumValues the enum values to check, typically the product of a call to MyEnum.values()
133 * @param constant the constant name to find (must not be null or empty string)
134 * @return whether the constant has been found in the given array
135 */
136 public static boolean containsConstant(Enum<?>[] enumValues, String constant) {
137 return containsConstant(enumValues, constant, false);
138 }
139
140 /**
141 * Check whether the given array of enum constants contains a constant with the given name.
142 *
143 * @param enumValues the enum values to check, typically the product of a call to MyEnum.values()
144 * @param constant the constant name to find (must not be null or empty string)
145 * @param caseSensitive whether case is significant in determining a match
146 * @return whether the constant has been found in the given array
147 */
148 public static boolean containsConstant(Enum<?>[] enumValues, String constant, boolean caseSensitive) {
149 for (Enum<?> candidate : enumValues) {
150 if (caseSensitive ?
151 candidate.toString().equals(constant) :
152 candidate.toString().equalsIgnoreCase(constant)) {
153 return true;
154 }
155 }
156 return false;
157 }
158
159 /**
160 * Case insensitive alternative to {@link Enum#valueOf(Class, String)}.
161 *
162 * @param <E> the concrete Enum type
163 * @param enumValues the array of all Enum constants in question, usually per Enum.values()
164 * @param constant the constant to get the enum value of
165 * @throws IllegalArgumentException if the given constant is not found in the given array
166 * of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to
167 * avoid this exception.
168 */
169 public static <E extends Enum<?>> E caseInsensitiveValueOf(E[] enumValues, String constant) {
170 for (E candidate : enumValues) {
171 if (candidate.toString().equalsIgnoreCase(constant)) {
172 return candidate;
173 }
174 }
175 throw new IllegalArgumentException(
176 String.format("constant [%s] does not exist in enum type %s",
177 constant, enumValues.getClass().getComponentType().getName()));
178 }
179
180 /**
181 * Append the given object to the given array, returning a new array
182 * consisting of the input array contents plus the given object.
183 *
184 * @param array the array to append to (can be <code>null</code>)
185 * @param obj the object to append
186 * @return the new array (of the same component type; never <code>null</code>)
187 */
188 public static <A, O extends A> A[] addObjectToArray(A[] array, O obj) {
189 Class<?> compType = Object.class;
190 if (array != null) {
191 compType = array.getClass().getComponentType();
192 } else if (obj != null) {
193 compType = obj.getClass();
194 }
195 int newArrLength = (array != null ? array.length + 1 : 1);
196 @SuppressWarnings("unchecked")
197 A[] newArr = (A[]) Array.newInstance(compType, newArrLength);
198 if (array != null) {
199 System.arraycopy(array, 0, newArr, 0, array.length);
200 }
201 newArr[newArr.length - 1] = obj;
202 return newArr;
203 }
204
205 /**
206 * Convert the given array (which may be a primitive array) to an
207 * object array (if necessary of primitive wrapper objects).
208 * <p>A <code>null</code> source value will be converted to an
209 * empty Object array.
210 *
211 * @param source the (potentially primitive) array
212 * @return the corresponding object array (never <code>null</code>)
213 * @throws IllegalArgumentException if the parameter is not an array
214 */
215 public static Object[] toObjectArray(Object source) {
216 if (source instanceof Object[]) {
217 return (Object[]) source;
218 }
219 if (source == null) {
220 return new Object[0];
221 }
222 if (!source.getClass().isArray()) {
223 throw new IllegalArgumentException("Source is not an array: " + source);
224 }
225 int length = Array.getLength(source);
226 if (length == 0) {
227 return new Object[0];
228 }
229 Class wrapperType = Array.get(source, 0).getClass();
230 Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
231 for (int i = 0; i < length; i++) {
232 newArray[i] = Array.get(source, i);
233 }
234 return newArray;
235 }
236
237
238 //---------------------------------------------------------------------
239 // Convenience methods for content-based equality/hash-code handling
240 //---------------------------------------------------------------------
241
242 /**
243 * Determine if the given objects are equal, returning <code>true</code>
244 * if both are <code>null</code> or <code>false</code> if only one is
245 * <code>null</code>.
246 * <p>Compares arrays with <code>Arrays.equals</code>, performing an equality
247 * check based on the array elements rather than the array reference.
248 *
249 * @param o1 first Object to compare
250 * @param o2 second Object to compare
251 * @return whether the given objects are equal
252 * @see java.util.Arrays#equals
253 */
254 public static boolean nullSafeEquals(Object o1, Object o2) {
255 if (o1 == o2) {
256 return true;
257 }
258 if (o1 == null || o2 == null) {
259 return false;
260 }
261 if (o1.equals(o2)) {
262 return true;
263 }
264 if (o1.getClass().isArray() && o2.getClass().isArray()) {
265 if (o1 instanceof Object[] && o2 instanceof Object[]) {
266 return Arrays.equals((Object[]) o1, (Object[]) o2);
267 }
268 if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
269 return Arrays.equals((boolean[]) o1, (boolean[]) o2);
270 }
271 if (o1 instanceof byte[] && o2 instanceof byte[]) {
272 return Arrays.equals((byte[]) o1, (byte[]) o2);
273 }
274 if (o1 instanceof char[] && o2 instanceof char[]) {
275 return Arrays.equals((char[]) o1, (char[]) o2);
276 }
277 if (o1 instanceof double[] && o2 instanceof double[]) {
278 return Arrays.equals((double[]) o1, (double[]) o2);
279 }
280 if (o1 instanceof float[] && o2 instanceof float[]) {
281 return Arrays.equals((float[]) o1, (float[]) o2);
282 }
283 if (o1 instanceof int[] && o2 instanceof int[]) {
284 return Arrays.equals((int[]) o1, (int[]) o2);
285 }
286 if (o1 instanceof long[] && o2 instanceof long[]) {
287 return Arrays.equals((long[]) o1, (long[]) o2);
288 }
289 if (o1 instanceof short[] && o2 instanceof short[]) {
290 return Arrays.equals((short[]) o1, (short[]) o2);
291 }
292 }
293 return false;
294 }
295
296 /**
297 * Return as hash code for the given object; typically the value of
298 * <code>{@link Object#hashCode()}</code>. If the object is an array,
299 * this method will delegate to any of the <code>nullSafeHashCode</code>
300 * methods for arrays in this class. If the object is <code>null</code>,
301 * this method returns 0.
302 *
303 * @see #nullSafeHashCode(Object[])
304 * @see #nullSafeHashCode(boolean[])
305 * @see #nullSafeHashCode(byte[])
306 * @see #nullSafeHashCode(char[])
307 * @see #nullSafeHashCode(double[])
308 * @see #nullSafeHashCode(float[])
309 * @see #nullSafeHashCode(int[])
310 * @see #nullSafeHashCode(long[])
311 * @see #nullSafeHashCode(short[])
312 */
313 public static int nullSafeHashCode(Object obj) {
314 if (obj == null) {
315 return 0;
316 }
317 if (obj.getClass().isArray()) {
318 if (obj instanceof Object[]) {
319 return nullSafeHashCode((Object[]) obj);
320 }
321 if (obj instanceof boolean[]) {
322 return nullSafeHashCode((boolean[]) obj);
323 }
324 if (obj instanceof byte[]) {
325 return nullSafeHashCode((byte[]) obj);
326 }
327 if (obj instanceof char[]) {
328 return nullSafeHashCode((char[]) obj);
329 }
330 if (obj instanceof double[]) {
331 return nullSafeHashCode((double[]) obj);
332 }
333 if (obj instanceof float[]) {
334 return nullSafeHashCode((float[]) obj);
335 }
336 if (obj instanceof int[]) {
337 return nullSafeHashCode((int[]) obj);
338 }
339 if (obj instanceof long[]) {
340 return nullSafeHashCode((long[]) obj);
341 }
342 if (obj instanceof short[]) {
343 return nullSafeHashCode((short[]) obj);
344 }
345 }
346 return obj.hashCode();
347 }
348
349 /**
350 * Return a hash code based on the contents of the specified array.
351 * If <code>array</code> is <code>null</code>, this method returns 0.
352 */
353 public static int nullSafeHashCode(Object[] array) {
354 if (array == null) {
355 return 0;
356 }
357 int hash = INITIAL_HASH;
358 int arraySize = array.length;
359 for (int i = 0; i < arraySize; i++) {
360 hash = MULTIPLIER * hash + nullSafeHashCode(array[i]);
361 }
362 return hash;
363 }
364
365 /**
366 * Return a hash code based on the contents of the specified array.
367 * If <code>array</code> is <code>null</code>, this method returns 0.
368 */
369 public static int nullSafeHashCode(boolean[] array) {
370 if (array == null) {
371 return 0;
372 }
373 int hash = INITIAL_HASH;
374 int arraySize = array.length;
375 for (int i = 0; i < arraySize; i++) {
376 hash = MULTIPLIER * hash + hashCode(array[i]);
377 }
378 return hash;
379 }
380
381 /**
382 * Return a hash code based on the contents of the specified array.
383 * If <code>array</code> is <code>null</code>, this method returns 0.
384 */
385 public static int nullSafeHashCode(byte[] array) {
386 if (array == null) {
387 return 0;
388 }
389 int hash = INITIAL_HASH;
390 int arraySize = array.length;
391 for (int i = 0; i < arraySize; i++) {
392 hash = MULTIPLIER * hash + array[i];
393 }
394 return hash;
395 }
396
397 /**
398 * Return a hash code based on the contents of the specified array.
399 * If <code>array</code> is <code>null</code>, this method returns 0.
400 */
401 public static int nullSafeHashCode(char[] array) {
402 if (array == null) {
403 return 0;
404 }
405 int hash = INITIAL_HASH;
406 int arraySize = array.length;
407 for (int i = 0; i < arraySize; i++) {
408 hash = MULTIPLIER * hash + array[i];
409 }
410 return hash;
411 }
412
413 /**
414 * Return a hash code based on the contents of the specified array.
415 * If <code>array</code> is <code>null</code>, this method returns 0.
416 */
417 public static int nullSafeHashCode(double[] array) {
418 if (array == null) {
419 return 0;
420 }
421 int hash = INITIAL_HASH;
422 int arraySize = array.length;
423 for (int i = 0; i < arraySize; i++) {
424 hash = MULTIPLIER * hash + hashCode(array[i]);
425 }
426 return hash;
427 }
428
429 /**
430 * Return a hash code based on the contents of the specified array.
431 * If <code>array</code> is <code>null</code>, this method returns 0.
432 */
433 public static int nullSafeHashCode(float[] array) {
434 if (array == null) {
435 return 0;
436 }
437 int hash = INITIAL_HASH;
438 int arraySize = array.length;
439 for (int i = 0; i < arraySize; i++) {
440 hash = MULTIPLIER * hash + hashCode(array[i]);
441 }
442 return hash;
443 }
444
445 /**
446 * Return a hash code based on the contents of the specified array.
447 * If <code>array</code> is <code>null</code>, this method returns 0.
448 */
449 public static int nullSafeHashCode(int[] array) {
450 if (array == null) {
451 return 0;
452 }
453 int hash = INITIAL_HASH;
454 int arraySize = array.length;
455 for (int i = 0; i < arraySize; i++) {
456 hash = MULTIPLIER * hash + array[i];
457 }
458 return hash;
459 }
460
461 /**
462 * Return a hash code based on the contents of the specified array.
463 * If <code>array</code> is <code>null</code>, this method returns 0.
464 */
465 public static int nullSafeHashCode(long[] array) {
466 if (array == null) {
467 return 0;
468 }
469 int hash = INITIAL_HASH;
470 int arraySize = array.length;
471 for (int i = 0; i < arraySize; i++) {
472 hash = MULTIPLIER * hash + hashCode(array[i]);
473 }
474 return hash;
475 }
476
477 /**
478 * Return a hash code based on the contents of the specified array.
479 * If <code>array</code> is <code>null</code>, this method returns 0.
480 */
481 public static int nullSafeHashCode(short[] array) {
482 if (array == null) {
483 return 0;
484 }
485 int hash = INITIAL_HASH;
486 int arraySize = array.length;
487 for (int i = 0; i < arraySize; i++) {
488 hash = MULTIPLIER * hash + array[i];
489 }
490 return hash;
491 }
492
493 /**
494 * Return the same value as <code>{@link Boolean#hashCode()}</code>.
495 *
496 * @see Boolean#hashCode()
497 */
498 public static int hashCode(boolean bool) {
499 return bool ? 1231 : 1237;
500 }
501
502 /**
503 * Return the same value as <code>{@link Double#hashCode()}</code>.
504 *
505 * @see Double#hashCode()
506 */
507 public static int hashCode(double dbl) {
508 long bits = Double.doubleToLongBits(dbl);
509 return hashCode(bits);
510 }
511
512 /**
513 * Return the same value as <code>{@link Float#hashCode()}</code>.
514 *
515 * @see Float#hashCode()
516 */
517 public static int hashCode(float flt) {
518 return Float.floatToIntBits(flt);
519 }
520
521 /**
522 * Return the same value as <code>{@link Long#hashCode()}</code>.
523 *
524 * @see Long#hashCode()
525 */
526 public static int hashCode(long lng) {
527 return (int) (lng ^ (lng >>> 32));
528 }
529
530
531 //---------------------------------------------------------------------
532 // Convenience methods for toString output
533 //---------------------------------------------------------------------
534
535 /**
536 * Return a String representation of an object's overall identity.
537 *
538 * @param obj the object (may be <code>null</code>)
539 * @return the object's identity as String representation,
540 * or an empty String if the object was <code>null</code>
541 */
542 public static String identityToString(Object obj) {
543 if (obj == null) {
544 return EMPTY_STRING;
545 }
546 return obj.getClass().getName() + "@" + getIdentityHexString(obj);
547 }
548
549 /**
550 * Return a hex String form of an object's identity hash code.
551 *
552 * @param obj the object
553 * @return the object's identity code in hex notation
554 */
555 public static String getIdentityHexString(Object obj) {
556 return Integer.toHexString(System.identityHashCode(obj));
557 }
558
559 /**
560 * Return a content-based String representation if <code>obj</code> is
561 * not <code>null</code>; otherwise returns an empty String.
562 * <p>Differs from {@link #nullSafeToString(Object)} in that it returns
563 * an empty String rather than "null" for a <code>null</code> value.
564 *
565 * @param obj the object to build a display String for
566 * @return a display String representation of <code>obj</code>
567 * @see #nullSafeToString(Object)
568 */
569 public static String getDisplayString(Object obj) {
570 if (obj == null) {
571 return EMPTY_STRING;
572 }
573 return nullSafeToString(obj);
574 }
575
576 /**
577 * Determine the class name for the given object.
578 * <p>Returns <code>"null"</code> if <code>obj</code> is <code>null</code>.
579 *
580 * @param obj the object to introspect (may be <code>null</code>)
581 * @return the corresponding class name
582 */
583 public static String nullSafeClassName(Object obj) {
584 return (obj != null ? obj.getClass().getName() : NULL_STRING);
585 }
586
587 /**
588 * Return a String representation of the specified Object.
589 * <p>Builds a String representation of the contents in case of an array.
590 * Returns <code>"null"</code> if <code>obj</code> is <code>null</code>.
591 *
592 * @param obj the object to build a String representation for
593 * @return a String representation of <code>obj</code>
594 */
595 public static String nullSafeToString(Object obj) {
596 if (obj == null) {
597 return NULL_STRING;
598 }
599 if (obj instanceof String) {
600 return (String) obj;
601 }
602 if (obj instanceof Object[]) {
603 return nullSafeToString((Object[]) obj);
604 }
605 if (obj instanceof boolean[]) {
606 return nullSafeToString((boolean[]) obj);
607 }
608 if (obj instanceof byte[]) {
609 return nullSafeToString((byte[]) obj);
610 }
611 if (obj instanceof char[]) {
612 return nullSafeToString((char[]) obj);
613 }
614 if (obj instanceof double[]) {
615 return nullSafeToString((double[]) obj);
616 }
617 if (obj instanceof float[]) {
618 return nullSafeToString((float[]) obj);
619 }
620 if (obj instanceof int[]) {
621 return nullSafeToString((int[]) obj);
622 }
623 if (obj instanceof long[]) {
624 return nullSafeToString((long[]) obj);
625 }
626 if (obj instanceof short[]) {
627 return nullSafeToString((short[]) obj);
628 }
629 String str = obj.toString();
630 return (str != null ? str : EMPTY_STRING);
631 }
632
633 /**
634 * Return a String representation of the contents of the specified array.
635 * <p>The String representation consists of a list of the array's elements,
636 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
637 * by the characters <code>", "</code> (a comma followed by a space). Returns
638 * <code>"null"</code> if <code>array</code> is <code>null</code>.
639 *
640 * @param array the array to build a String representation for
641 * @return a String representation of <code>array</code>
642 */
643 public static String nullSafeToString(Object[] array) {
644 if (array == null) {
645 return NULL_STRING;
646 }
647 int length = array.length;
648 if (length == 0) {
649 return EMPTY_ARRAY;
650 }
651 StringBuilder sb = new StringBuilder();
652 for (int i = 0; i < length; i++) {
653 if (i == 0) {
654 sb.append(ARRAY_START);
655 } else {
656 sb.append(ARRAY_ELEMENT_SEPARATOR);
657 }
658 sb.append(String.valueOf(array[i]));
659 }
660 sb.append(ARRAY_END);
661 return sb.toString();
662 }
663
664 /**
665 * Return a String representation of the contents of the specified array.
666 * <p>The String representation consists of a list of the array's elements,
667 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
668 * by the characters <code>", "</code> (a comma followed by a space). Returns
669 * <code>"null"</code> if <code>array</code> is <code>null</code>.
670 *
671 * @param array the array to build a String representation for
672 * @return a String representation of <code>array</code>
673 */
674 public static String nullSafeToString(boolean[] array) {
675 if (array == null) {
676 return NULL_STRING;
677 }
678 int length = array.length;
679 if (length == 0) {
680 return EMPTY_ARRAY;
681 }
682 StringBuilder sb = new StringBuilder();
683 for (int i = 0; i < length; i++) {
684 if (i == 0) {
685 sb.append(ARRAY_START);
686 } else {
687 sb.append(ARRAY_ELEMENT_SEPARATOR);
688 }
689
690 sb.append(array[i]);
691 }
692 sb.append(ARRAY_END);
693 return sb.toString();
694 }
695
696 /**
697 * Return a String representation of the contents of the specified array.
698 * <p>The String representation consists of a list of the array's elements,
699 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
700 * by the characters <code>", "</code> (a comma followed by a space). Returns
701 * <code>"null"</code> if <code>array</code> is <code>null</code>.
702 *
703 * @param array the array to build a String representation for
704 * @return a String representation of <code>array</code>
705 */
706 public static String nullSafeToString(byte[] array) {
707 if (array == null) {
708 return NULL_STRING;
709 }
710 int length = array.length;
711 if (length == 0) {
712 return EMPTY_ARRAY;
713 }
714 StringBuilder sb = new StringBuilder();
715 for (int i = 0; i < length; i++) {
716 if (i == 0) {
717 sb.append(ARRAY_START);
718 } else {
719 sb.append(ARRAY_ELEMENT_SEPARATOR);
720 }
721 sb.append(array[i]);
722 }
723 sb.append(ARRAY_END);
724 return sb.toString();
725 }
726
727 /**
728 * Return a String representation of the contents of the specified array.
729 * <p>The String representation consists of a list of the array's elements,
730 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
731 * by the characters <code>", "</code> (a comma followed by a space). Returns
732 * <code>"null"</code> if <code>array</code> is <code>null</code>.
733 *
734 * @param array the array to build a String representation for
735 * @return a String representation of <code>array</code>
736 */
737 public static String nullSafeToString(char[] array) {
738 if (array == null) {
739 return NULL_STRING;
740 }
741 int length = array.length;
742 if (length == 0) {
743 return EMPTY_ARRAY;
744 }
745 StringBuilder sb = new StringBuilder();
746 for (int i = 0; i < length; i++) {
747 if (i == 0) {
748 sb.append(ARRAY_START);
749 } else {
750 sb.append(ARRAY_ELEMENT_SEPARATOR);
751 }
752 sb.append("'").append(array[i]).append("'");
753 }
754 sb.append(ARRAY_END);
755 return sb.toString();
756 }
757
758 /**
759 * Return a String representation of the contents of the specified array.
760 * <p>The String representation consists of a list of the array's elements,
761 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
762 * by the characters <code>", "</code> (a comma followed by a space). Returns
763 * <code>"null"</code> if <code>array</code> is <code>null</code>.
764 *
765 * @param array the array to build a String representation for
766 * @return a String representation of <code>array</code>
767 */
768 public static String nullSafeToString(double[] array) {
769 if (array == null) {
770 return NULL_STRING;
771 }
772 int length = array.length;
773 if (length == 0) {
774 return EMPTY_ARRAY;
775 }
776 StringBuilder sb = new StringBuilder();
777 for (int i = 0; i < length; i++) {
778 if (i == 0) {
779 sb.append(ARRAY_START);
780 } else {
781 sb.append(ARRAY_ELEMENT_SEPARATOR);
782 }
783
784 sb.append(array[i]);
785 }
786 sb.append(ARRAY_END);
787 return sb.toString();
788 }
789
790 /**
791 * Return a String representation of the contents of the specified array.
792 * <p>The String representation consists of a list of the array's elements,
793 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
794 * by the characters <code>", "</code> (a comma followed by a space). Returns
795 * <code>"null"</code> if <code>array</code> is <code>null</code>.
796 *
797 * @param array the array to build a String representation for
798 * @return a String representation of <code>array</code>
799 */
800 public static String nullSafeToString(float[] array) {
801 if (array == null) {
802 return NULL_STRING;
803 }
804 int length = array.length;
805 if (length == 0) {
806 return EMPTY_ARRAY;
807 }
808 StringBuilder sb = new StringBuilder();
809 for (int i = 0; i < length; i++) {
810 if (i == 0) {
811 sb.append(ARRAY_START);
812 } else {
813 sb.append(ARRAY_ELEMENT_SEPARATOR);
814 }
815
816 sb.append(array[i]);
817 }
818 sb.append(ARRAY_END);
819 return sb.toString();
820 }
821
822 /**
823 * Return a String representation of the contents of the specified array.
824 * <p>The String representation consists of a list of the array's elements,
825 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
826 * by the characters <code>", "</code> (a comma followed by a space). Returns
827 * <code>"null"</code> if <code>array</code> is <code>null</code>.
828 *
829 * @param array the array to build a String representation for
830 * @return a String representation of <code>array</code>
831 */
832 public static String nullSafeToString(int[] array) {
833 if (array == null) {
834 return NULL_STRING;
835 }
836 int length = array.length;
837 if (length == 0) {
838 return EMPTY_ARRAY;
839 }
840 StringBuilder sb = new StringBuilder();
841 for (int i = 0; i < length; i++) {
842 if (i == 0) {
843 sb.append(ARRAY_START);
844 } else {
845 sb.append(ARRAY_ELEMENT_SEPARATOR);
846 }
847 sb.append(array[i]);
848 }
849 sb.append(ARRAY_END);
850 return sb.toString();
851 }
852
853 /**
854 * Return a String representation of the contents of the specified array.
855 * <p>The String representation consists of a list of the array's elements,
856 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
857 * by the characters <code>", "</code> (a comma followed by a space). Returns
858 * <code>"null"</code> if <code>array</code> is <code>null</code>.
859 *
860 * @param array the array to build a String representation for
861 * @return a String representation of <code>array</code>
862 */
863 public static String nullSafeToString(long[] array) {
864 if (array == null) {
865 return NULL_STRING;
866 }
867 int length = array.length;
868 if (length == 0) {
869 return EMPTY_ARRAY;
870 }
871 StringBuilder sb = new StringBuilder();
872 for (int i = 0; i < length; i++) {
873 if (i == 0) {
874 sb.append(ARRAY_START);
875 } else {
876 sb.append(ARRAY_ELEMENT_SEPARATOR);
877 }
878 sb.append(array[i]);
879 }
880 sb.append(ARRAY_END);
881 return sb.toString();
882 }
883
884 /**
885 * Return a String representation of the contents of the specified array.
886 * <p>The String representation consists of a list of the array's elements,
887 * enclosed in curly braces (<code>"{}"</code>). Adjacent elements are separated
888 * by the characters <code>", "</code> (a comma followed by a space). Returns
889 * <code>"null"</code> if <code>array</code> is <code>null</code>.
890 *
891 * @param array the array to build a String representation for
892 * @return a String representation of <code>array</code>
893 */
894 public static String nullSafeToString(short[] array) {
895 if (array == null) {
896 return NULL_STRING;
897 }
898 int length = array.length;
899 if (length == 0) {
900 return EMPTY_ARRAY;
901 }
902 StringBuilder sb = new StringBuilder();
903 for (int i = 0; i < length; i++) {
904 if (i == 0) {
905 sb.append(ARRAY_START);
906 } else {
907 sb.append(ARRAY_ELEMENT_SEPARATOR);
908 }
909 sb.append(array[i]);
910 }
911 sb.append(ARRAY_END);
912 return sb.toString();
913 }
914
915 public static void nullSafeClose(Closeable... closeables) {
916 if (closeables == null) {
917 return;
918 }
919
920 for (Closeable closeable : closeables) {
921 if (closeable != null) {
922 try {
923 closeable.close();
924 } catch (IOException e) {
925 //Ignore the exception during close.
926 }
927 }
928 }
929 }
930 }
931