001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.commons.utils; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020import static org.apache.juneau.commons.utils.StringUtils.*; 021import static org.apache.juneau.commons.utils.ThrowableUtils.*; 022import java.lang.reflect.*; 023import java.nio.charset.*; 024import java.text.*; 025import java.util.*; 026import java.util.concurrent.atomic.*; 027import java.util.function.*; 028 029import org.apache.juneau.commons.function.*; 030import org.apache.juneau.commons.lang.*; 031import org.apache.juneau.commons.settings.*; 032 033/** 034 * Common utility methods. 035 * 036 * <p> 037 * This class contains various static utility methods for working with collections, strings, objects, and other common operations. 038 * 039 * <h5 class='section'>Features:</h5> 040 * <ul> 041 * <li><b>Collections:</b> Array and list creation, conversion, and manipulation 042 * <li><b>Strings:</b> Formatting, comparison, and null-safe operations 043 * <li><b>Objects:</b> Equality checking, casting, and null handling 044 * <li><b>Environment:</b> System property and environment variable access 045 * <li><b>Optionals:</b> Enhanced Optional operations and conversions 046 * </ul> 047 * 048 * <h5 class='section'>See Also:</h5> 049 * <ul> 050 * <li class='jc'>{@link AssertionUtils} - For argument validation and assertion methods 051 * <li class='jc'>{@link StringUtils} - For additional string manipulation utilities 052 * <li class='link'><a class="doclink" href='../../../../../index.html#juneau-commons.utils'>Overview > juneau-commons.utils</a> 053 * </ul> 054 */ 055public class Utils { 056 057 /** 058 * Converts an object to a boolean. 059 * 060 * @param val The object to convert. 061 * @return The boolean value, or <jk>false</jk> if the value was <jk>null</jk>. 062 */ 063 public static boolean bool(Object val) { 064 return opt(val).map(Object::toString).map(Boolean::valueOf).orElse(false); 065 } 066 067 /** 068 * Casts an object to a specific type if it's an instance of that type. 069 * 070 * <p> 071 * This is a null-safe and type-safe casting operation. Returns <jk>null</jk> if: 072 * <ul> 073 * <li>The object is <jk>null</jk></li> 074 * <li>The object is not an instance of the specified type</li> 075 * </ul> 076 * 077 * <p> 078 * <b>Behavior for incorrect instance types:</b> If the object is not an instance of the specified type, 079 * this method returns <jk>null</jk> rather than throwing a {@link ClassCastException}. This makes it 080 * safe to use when you're unsure of the object's type and want to handle type mismatches gracefully. 081 * 082 * <h5 class='section'>Example:</h5> 083 * <p class='bjava'> 084 * Object <jv>obj</jv> = <js>"Hello"</js>; 085 * String <jv>str</jv> = cast(String.<jk>class</jk>, <jv>obj</jv>); <jc>// "Hello"</jc> 086 * Integer <jv>num</jv> = cast(Integer.<jk>class</jk>, <jv>obj</jv>); <jc>// null (not an Integer, no exception thrown)</jc> 087 * String <jv>str2</jv> = cast(String.<jk>class</jk>, <jk>null</jk>); <jc>// null</jc> 088 * </p> 089 * 090 * @param <T> The type to cast to. 091 * @param c The type to cast to. 092 * @param o The object to cast. 093 * @return The cast object, or <jk>null</jk> if the object wasn't the specified type or was <jk>null</jk>. 094 */ 095 public static <T> T cast(Class<T> c, Object o) { 096 return nn(o) && c.isInstance(o) ? c.cast(o) : null; 097 } 098 099 /** 100 * Shortcut for calling {@link ClassUtils#className(Object)}. 101 * 102 * <p> 103 * Returns the fully-qualified class name including the full package path. 104 * 105 * <h5 class='section'>Examples:</h5> 106 * <p class='bjava'> 107 * <jc>// Regular classes</jc> 108 * cn(String.<jk>class</jk>); <jc>// "java.lang.String"</jc> 109 * cn(<jk>new</jk> HashMap<>()); <jc>// "java.util.HashMap"</jc> 110 * 111 * <jc>// Inner classes</jc> 112 * cn(Map.Entry.<jk>class</jk>); <jc>// "java.util.Map$Entry"</jc> 113 * 114 * <jc>// Primitives</jc> 115 * cn(<jk>int</jk>.<jk>class</jk>); <jc>// "int"</jc> 116 * cn(<jk>boolean</jk>.<jk>class</jk>); <jc>// "boolean"</jc> 117 * 118 * <jc>// Arrays</jc> 119 * cn(String[].<jk>class</jk>); <jc>// "[Ljava.lang.String;"</jc> 120 * cn(<jk>int</jk>[].<jk>class</jk>); <jc>// "[I"</jc> 121 * cn(String[][].<jk>class</jk>); <jc>// "[[Ljava.lang.String;"</jc> 122 * 123 * <jc>// Null</jc> 124 * cn(<jk>null</jk>); <jc>// null</jc> 125 * </p> 126 * 127 * @param value The object to get the class name for. 128 * @return The name of the class or <jk>null</jk> if the value was null. 129 */ 130 public static String cn(Object value) { 131 return ClassUtils.className(value); 132 } 133 134 /** 135 * Shortcut for calling {@link ClassUtils#classNameSimple(Object)}. 136 * 137 * <p> 138 * Returns only the simple class name without any package or outer class information. 139 * For inner classes, only the innermost class name is returned. 140 * 141 * <h5 class='section'>Examples:</h5> 142 * <p class='bjava'> 143 * <jc>// Regular classes</jc> 144 * scn(String.<jk>class</jk>); <jc>// "String"</jc> 145 * scn(<jk>new</jk> HashMap<>()); <jc>// "HashMap"</jc> 146 * 147 * <jc>// Inner classes</jc> 148 * scn(Map.Entry.<jk>class</jk>); <jc>// "Entry"</jc> 149 * 150 * <jc>// Primitives</jc> 151 * scn(<jk>int</jk>.<jk>class</jk>); <jc>// "int"</jc> 152 * scn(<jk>boolean</jk>.<jk>class</jk>); <jc>// "boolean"</jc> 153 * 154 * <jc>// Arrays</jc> 155 * scn(String[].<jk>class</jk>); <jc>// "String[]"</jc> 156 * scn(<jk>int</jk>[].<jk>class</jk>); <jc>// "int[]"</jc> 157 * scn(String[][].<jk>class</jk>); <jc>// "String[][]"</jc> 158 * 159 * <jc>// Null</jc> 160 * scn(<jk>null</jk>); <jc>// null</jc> 161 * </p> 162 * 163 * @param value The object to get the simple class name for. 164 * @return The simple name of the class or <jk>null</jk> if the value was null. 165 */ 166 public static String cns(Object value) { 167 return ClassUtils.classNameSimple(value); 168 } 169 170 /** 171 * Shortcut for calling {@link ClassUtils#classNameSimpleQualified(Object)}. 172 * 173 * <p> 174 * Returns the simple class name including outer class names, but without the package. 175 * Inner class separators ($) are replaced with dots (.). 176 * Array types are properly formatted with brackets. 177 * 178 * <h5 class='section'>Examples:</h5> 179 * <p class='bjava'> 180 * <jc>// Regular classes</jc> 181 * sqcn(String.<jk>class</jk>); <jc>// "String"</jc> 182 * sqcn(<jk>new</jk> HashMap<>()); <jc>// "HashMap"</jc> 183 * 184 * <jc>// Inner classes</jc> 185 * sqcn(Map.Entry.<jk>class</jk>); <jc>// "Map.Entry"</jc> 186 * sqcn(Outer.Inner.Deep.<jk>class</jk>); <jc>// "Outer.Inner.Deep"</jc> 187 * 188 * <jc>// Primitives</jc> 189 * sqcn(<jk>int</jk>.<jk>class</jk>); <jc>// "int"</jc> 190 * sqcn(<jk>boolean</jk>.<jk>class</jk>); <jc>// "boolean"</jc> 191 * 192 * <jc>// Object arrays</jc> 193 * sqcn(String[].<jk>class</jk>); <jc>// "String[]"</jc> 194 * sqcn(Map.Entry[].<jk>class</jk>); <jc>// "Map.Entry[]"</jc> 195 * sqcn(String[][].<jk>class</jk>); <jc>// "String[][]"</jc> 196 * 197 * <jc>// Primitive arrays</jc> 198 * sqcn(<jk>int</jk>[].<jk>class</jk>); <jc>// "int[]"</jc> 199 * sqcn(<jk>boolean</jk>[][].<jk>class</jk>); <jc>// "boolean[][]"</jc> 200 * 201 * <jc>// Null</jc> 202 * sqcn(<jk>null</jk>); <jc>// null</jc> 203 * </p> 204 * 205 * @param value The object to get the simple qualified class name for. 206 * @return The simple qualified name of the class or <jk>null</jk> if the value was null. 207 */ 208 public static String cnsq(Object value) { 209 return ClassUtils.classNameSimpleQualified(value); 210 } 211 212 /** 213 * Compares two objects for ordering. 214 * 215 * <p> 216 * This method attempts to compare two objects using their natural ordering if they implement 217 * {@link Comparable} and are of the same type. Null handling: 218 * <ul> 219 * <li>Both <jk>null</jk> → returns <c>0</c> (equal)</li> 220 * <li>First <jk>null</jk> → returns <c>-1</c> (null is less-than)</li> 221 * <li>Second <jk>null</jk> → returns <c>1</c> (null is less-than)</li> 222 * <li>Different types or not Comparable → returns <c>0</c> (cannot compare)</li> 223 * </ul> 224 * 225 * <h5 class='section'>Example:</h5> 226 * <p class='bjava'> 227 * cmp(<js>"apple"</js>, <js>"banana"</js>); <jc>// negative (apple < banana)</jc> 228 * cmp(5, 10); <jc>// negative (5 < 10)</jc> 229 * cmp(<js>"apple"</js>, <js>"apple"</js>); <jc>// 0 (equal)</jc> 230 * cmp(<jk>null</jk>, <jk>null</jk>); <jc>// 0 (equal)</jc> 231 * cmp(<jk>null</jk>, <js>"apple"</js>); <jc>// -1 (null < non-null)</jc> 232 * cmp(<js>"apple"</js>, 5); <jc>// 0 (different types, cannot compare)</jc> 233 * </p> 234 * 235 * @param o1 Object 1. 236 * @param o2 Object 2. 237 * @return <c>-1</c>, <c>0</c>, or <c>1</c> if <c>o1</c> is less-than, equal, or greater-than <c>o2</c>. 238 * Returns <c>0</c> if objects are not of the same type or do not implement the {@link Comparable} interface. 239 */ 240 @SuppressWarnings("unchecked") 241 public static int cmp(Object o1, Object o2) { 242 if (o1 == null) { 243 if (o2 == null) 244 return 0; 245 return -1; 246 } else if (o2 == null) { 247 return 1; 248 } 249 250 if (eq(o1.getClass(), o2.getClass()) && o1 instanceof Comparable o1a) 251 return o1a.compareTo(o2); 252 253 return 0; 254 } 255 256 /** 257 * Tests if the first object is less than the second object. 258 * 259 * <p> 260 * Uses natural ordering if both objects implement {@link Comparable} and are of the same type. 261 * 262 * <h5 class='section'>Example:</h5> 263 * <p class='bjava'> 264 * lt(5, 10); <jc>// true</jc> 265 * lt(<js>"apple"</js>, <js>"banana"</js>); <jc>// true</jc> 266 * lt(10, 5); <jc>// false</jc> 267 * lt(5, 5); <jc>// false</jc> 268 * </p> 269 * 270 * @param <T> The object type. 271 * @param o1 Object 1. 272 * @param o2 Object 2. 273 * @return <jk>true</jk> if <c>o1</c> is less than <c>o2</c>. 274 * @see #cmp(Object, Object) 275 */ 276 public static <T extends Comparable<T>> boolean lt(T o1, T o2) { 277 if (o1 == null) return o2 != null; 278 if (o2 == null) return false; 279 return o1.compareTo(o2) < 0; 280 } 281 282 /** 283 * Tests if the first object is less than or equal to the second object. 284 * 285 * <p> 286 * Uses natural ordering if both objects implement {@link Comparable} and are of the same type. 287 * 288 * <h5 class='section'>Example:</h5> 289 * <p class='bjava'> 290 * lte(5, 10); <jc>// true</jc> 291 * lte(5, 5); <jc>// true</jc> 292 * lte(10, 5); <jc>// false</jc> 293 * </p> 294 * 295 * @param <T> The object type. 296 * @param o1 Object 1. 297 * @param o2 Object 2. 298 * @return <jk>true</jk> if <c>o1</c> is less than or equal to <c>o2</c>. 299 * @see #cmp(Object, Object) 300 */ 301 public static <T extends Comparable<T>> boolean lte(T o1, T o2) { 302 if (o1 == null) return true; 303 if (o2 == null) return false; 304 return o1.compareTo(o2) <= 0; 305 } 306 307 /** 308 * Tests if the first object is greater than the second object. 309 * 310 * <p> 311 * Uses natural ordering if both objects implement {@link Comparable} and are of the same type. 312 * 313 * <h5 class='section'>Example:</h5> 314 * <p class='bjava'> 315 * gt(10, 5); <jc>// true</jc> 316 * gt(<js>"banana"</js>, <js>"apple"</js>); <jc>// true</jc> 317 * gt(5, 10); <jc>// false</jc> 318 * gt(5, 5); <jc>// false</jc> 319 * </p> 320 * 321 * @param <T> The object type. 322 * @param o1 Object 1. 323 * @param o2 Object 2. 324 * @return <jk>true</jk> if <c>o1</c> is greater than <c>o2</c>. 325 * @see #cmp(Object, Object) 326 */ 327 public static <T extends Comparable<T>> boolean gt(T o1, T o2) { 328 if (o1 == null) return false; 329 if (o2 == null) return true; 330 return o1.compareTo(o2) > 0; 331 } 332 333 /** 334 * Tests if the first object is greater than or equal to the second object. 335 * 336 * <p> 337 * Uses natural ordering if both objects implement {@link Comparable} and are of the same type. 338 * 339 * <h5 class='section'>Example:</h5> 340 * <p class='bjava'> 341 * gte(10, 5); <jc>// true</jc> 342 * gte(5, 5); <jc>// true</jc> 343 * gte(5, 10); <jc>// false</jc> 344 * </p> 345 * 346 * @param <T> The object type. 347 * @param o1 Object 1. 348 * @param o2 Object 2. 349 * @return <jk>true</jk> if <c>o1</c> is greater than or equal to <c>o2</c>. 350 * @see #cmp(Object, Object) 351 */ 352 public static <T extends Comparable<T>> boolean gte(T o1, T o2) { 353 if (o1 == null) return o2 == null; 354 if (o2 == null) return true; 355 return o1.compareTo(o2) >= 0; 356 } 357 358 /** 359 * Creates an empty array of the specified type. 360 * 361 * <p> 362 * This is a convenience method for creating empty arrays using reflection. Useful when you need 363 * an empty array of a specific type but don't have an instance to call <c>new T[0]</c>. 364 * 365 * <h5 class='section'>Example:</h5> 366 * <p class='bjava'> 367 * String[] <jv>empty</jv> = ea(String.<jk>class</jk>); <jc>// new String[0]</jc> 368 * Integer[] <jv>empty2</jv> = ea(Integer.<jk>class</jk>); <jc>// new Integer[0]</jc> 369 * List<String>[] <jv>empty3</jv> = ea(List.<jk>class</jk>); <jc>// new List[0]</jc> 370 * </p> 371 * 372 * @param <T> The component type of the array. 373 * @param type The component type class. 374 * @return An empty array of the specified type. 375 */ 376 @SuppressWarnings("unchecked") 377 public static <T> T[] ea(Class<T> type) { 378 return (T[])Array.newInstance(type, 0); 379 } 380 381 /** 382 * Returns the string representation of an object, or an empty string if the object is <jk>null</jk>. 383 * 384 * <p> 385 * This is a null-safe string conversion method. If the object is <jk>null</jk>, returns an empty string. 386 * Otherwise, returns the result of calling {@link Object#toString()} on the object. 387 * 388 * <h5 class='section'>Example:</h5> 389 * <p class='bjava'> 390 * emptyIfNull(<js>"Hello"</js>); <jc>// "Hello"</jc> 391 * emptyIfNull(123); <jc>// "123"</jc> 392 * emptyIfNull(<jk>null</jk>); <jc>// ""</jc> 393 * </p> 394 * 395 * @param value The value to convert to a string. Can be <jk>null</jk>. 396 * @return The string representation of the value, or an empty string if <jk>null</jk>. 397 * @see Object#toString() 398 */ 399 public static String emptyIfNull(Object value) { 400 return value == null ? "" : value.toString(); 401 } 402 403 /** 404 * Looks up a system property or environment variable. 405 * 406 * <p> 407 * This method searches for a value in the following order: 408 * <ol> 409 * <li>System properties (via {@link System#getProperty(String)})</li> 410 * <li>Environment variables (via {@link System#getenv(String)}) - the name is converted to env-safe format</li> 411 * </ol> 412 * 413 * <p> 414 * Returns an empty {@link Optional} if the value is not found in either location. 415 * 416 * <h5 class='section'>Example:</h5> 417 * <p class='bjava'> 418 * <jc>// System property: -Dmy.property=value</jc> 419 * Optional<String> <jv>prop</jv> = env(<js>"my.property"</js>); <jc>// Optional.of("value")</jc> 420 * 421 * <jc>// Environment variable: MY_PROPERTY=value</jc> 422 * Optional<String> <jv>env</jv> = env(<js>"my.property"</js>); <jc>// Optional.of("value") (converts to MY_PROPERTY)</jc> 423 * 424 * Optional<String> <jv>missing</jv> = env(<js>"nonexistent"</js>); <jc>// Optional.empty()</jc> 425 * </p> 426 * 427 * @param name The property name (will be converted to env-safe format for environment variable lookup). 428 * @return An {@link Optional} containing the value if found, or empty if not found. 429 * @see #env(String, Object) 430 * @see System#getProperty(String) 431 * @see System#getenv(String) 432 */ 433 public static StringSetting env(String name) { 434 return Settings.get().get(name); 435 } 436 437 /** 438 * Looks up a system property or environment variable, returning a default value if not found. 439 * 440 * <p> 441 * This method searches for a value in the following order: 442 * <ol> 443 * <li>System properties (via {@link System#getProperty(String)})</li> 444 * <li>Environment variables (via {@link System#getenv(String)}) - the name is converted to env-safe format</li> 445 * <li>Returns the default value if not found</li> 446 * </ol> 447 * 448 * <p> 449 * If a value is found, it is converted to the type of the default value using the Settings framework. 450 * Supported types include {@link Boolean}, {@link Charset}, and other common types. 451 * 452 * <h5 class='section'>Example:</h5> 453 * <p class='bjava'> 454 * <jc>// System property: -Dmy.property=true</jc> 455 * Boolean <jv>flag</jv> = env(<js>"my.property"</js>, <jk>false</jk>); <jc>// true</jc> 456 * 457 * <jc>// Environment variable: MY_PROPERTY=UTF-8</jc> 458 * Charset <jv>charset</jv> = env(<js>"my.property"</js>, Charset.defaultCharset()); <jc>// UTF-8</jc> 459 * 460 * <jc>// Not found, returns default</jc> 461 * String <jv>value</jv> = env(<js>"nonexistent"</js>, <js>"default"</js>); <jc>// "default"</jc> 462 * </p> 463 * 464 * @param <T> The type to convert the value to. 465 * @param name The property name (will be converted to env-safe format for environment variable lookup). 466 * @param def The default value to return if not found. 467 * @return The found value (converted to type T), or the default value if not found. 468 * @see #env(String) 469 */ 470 public static <T> T env(String name, T def) { 471 return Settings.get().get(name, def); 472 } 473 474 /** 475 * Tests two strings for equality, with optional case-insensitive matching. 476 * 477 * <p> 478 * This method provides a unified way to compare strings with or without case sensitivity. 479 * Both strings are handled gracefully for <jk>null</jk> values. 480 * 481 * <h5 class='section'>Example:</h5> 482 * <p class='bjava'> 483 * eq(<jk>false</jk>, <js>"Hello"</js>, <js>"Hello"</js>); <jc>// true (case-sensitive)</jc> 484 * eq(<jk>false</jk>, <js>"Hello"</js>, <js>"hello"</js>); <jc>// false (case-sensitive)</jc> 485 * eq(<jk>true</jk>, <js>"Hello"</js>, <js>"hello"</js>); <jc>// true (case-insensitive)</jc> 486 * eq(<jk>false</jk>, <jk>null</jk>, <jk>null</jk>); <jc>// true (both null)</jc> 487 * eq(<jk>false</jk>, <js>"Hello"</js>, <jk>null</jk>); <jc>// false</jc> 488 * </p> 489 * 490 * @param caseInsensitive Use case-insensitive matching. 491 * @param s1 String 1. 492 * @param s2 String 2. 493 * @return <jk>true</jk> if the strings are equal (according to the case sensitivity setting). 494 * @see #eq(Object, Object) 495 * @see #eqic(String, String) 496 */ 497 public static boolean eq(boolean caseInsensitive, String s1, String s2) { 498 return caseInsensitive ? eqic(s1, s2) : eq(s1, s2); 499 } 500 501 /** 502 * Tests two objects for equality, gracefully handling nulls and arrays. 503 * 504 * <p> 505 * This method handles annotations specially by delegating to {@link org.apache.juneau.commons.utils.AnnotationUtils#equals(java.lang.annotation.Annotation, java.lang.annotation.Annotation)} 506 * to ensure proper annotation comparison according to the annotation equality contract. 507 * 508 * @param <T> The value types. 509 * @param o1 Object 1. 510 * @param o2 Object 2. 511 * @return <jk>true</jk> if both objects are equal based on the {@link Object#equals(Object)} method. 512 * @see org.apache.juneau.commons.utils.AnnotationUtils#equals(java.lang.annotation.Annotation, java.lang.annotation.Annotation) 513 */ 514 public static <T> boolean eq(T o1, T o2) { 515 // Handle annotations specially 516 if (o1 instanceof java.lang.annotation.Annotation o1a && o2 instanceof java.lang.annotation.Annotation o2a) 517 return AnnotationUtils.equals(o1a, o2a); 518 519 if (isArray(o1) && isArray(o2)) { 520 int l1 = Array.getLength(o1), l2 = Array.getLength(o2); 521 if (l1 != l2) 522 return false; 523 for (var i = 0; i < l1; i++) 524 if (neq(Array.get(o1, i), Array.get(o2, i))) 525 return false; 526 return true; 527 } 528 return Objects.equals(o1, o2); 529 } 530 531 /** 532 * Tests two objects for equality using a custom predicate, gracefully handling nulls. 533 * 534 * <p> 535 * This method provides a convenient way to implement custom equality logic while handling null values 536 * safely. The predicate is only called if both objects are non-null and not the same reference. 537 * 538 * <h5 class='section'>Example:</h5> 539 * <p class='bjava'> 540 * <jc>// Custom equality for a Role class</jc> 541 * <jk>public</jk> <jk>boolean</jk> equals(Object o) { 542 * <jk>return</jk> eq(<jk>this</jk>, (Role)o, (x,y) -> 543 * eq(x.id, y.id) && 544 * eq(x.name, y.name) && 545 * eq(x.created, y.created) && 546 * eq(x.createdBy, y.createdBy) 547 * ); 548 * } 549 * 550 * <jc>// Usage</jc> 551 * Role <jv>r1</jv> = <jk>new</jk> Role(1, <js>"admin"</js>); 552 * Role <jv>r2</jv> = <jk>new</jk> Role(1, <js>"admin"</js>); 553 * eq(<jv>r1</jv>, <jv>r2</jv>, (x,y) -> x.id == y.id && x.name.equals(y.name)); <jc>// true</jc> 554 * </p> 555 * 556 * @param <T> Object 1 type. 557 * @param <U> Object 2 type. 558 * @param o1 Object 1. 559 * @param o2 Object 2. 560 * @param test The predicate to use for equality testing (only called if both objects are non-null and different references). 561 * @return <jk>true</jk> if both objects are equal based on the test, or if both are <jk>null</jk>, or if they are the same reference. 562 * @see #eq(Object, Object) 563 */ 564 public static <T,U> boolean eq(T o1, U o2, BiPredicate<T,U> test) { 565 if (o1 == null) { 566 return o2 == null; 567 } 568 if (o2 == null) { 569 return false; 570 } 571 if (o1 == o2) { 572 return true; 573 } 574 return test.test(o1, o2); 575 } 576 577 /** 578 * Convenience method for calling {@link StringUtils#equalsIgnoreCase(Object, Object)}. 579 * 580 * <p> 581 * Tests two objects for case-insensitive string equality by converting them to strings. 582 * 583 * @param o1 Object 1. 584 * @param o2 Object 2. 585 * @return <jk>true</jk> if both objects are equal ignoring case. 586 */ 587 public static boolean eqic(Object o1, Object o2) { 588 return StringUtils.equalsIgnoreCase(o1, o2); 589 } 590 591 /** 592 * Convenience method for calling {@link StringUtils#equalsIgnoreCase(String, String)}. 593 * 594 * <p> 595 * Tests two strings for case-insensitive equality, but gracefully handles nulls. 596 * 597 * @param s1 String 1. 598 * @param s2 String 2. 599 * @return <jk>true</jk> if the strings are equal. 600 */ 601 public static boolean eqic(String s1, String s2) { 602 return StringUtils.equalsIgnoreCase(s1, s2); 603 } 604 605 /** 606 * Shortcut for calling {@link StringUtils#format(String, Object...)}. 607 * 608 * <p> 609 * This method provides a convenient shorthand for string formatting that supports both 610 * MessageFormat-style and printf-style formatting in the same pattern. 611 * 612 * <h5 class='section'>Format Support:</h5> 613 * <ul> 614 * <li><b>Printf-style:</b> <js>"%s"</js>, <js>"%d"</js>, <js>"%.2f"</js>, <js>"%1$s"</js>, etc.</li> 615 * <li><b>MessageFormat-style:</b> <js>"{0}"</js>, <js>"{1,number}"</js>, <js>"{2,date}"</js>, etc.</li> 616 * <li><b>Un-numbered MessageFormat:</b> <js>"{}"</js> - Sequential placeholders that are automatically numbered</li> 617 * <li><b>Mixed formats:</b> Both styles can be used in the same pattern</li> 618 * </ul> 619 * 620 * <h5 class='section'>Examples:</h5> 621 * <p class='bjava'> 622 * <jc>// Printf-style formatting</jc> 623 * f(<js>"Hello %s, you have %d items"</js>, <js>"John"</js>, 5); 624 * <jc>// Returns: "Hello John, you have 5 items"</jc> 625 * 626 * <jc>// Floating point</jc> 627 * f(<js>"Price: $%.2f"</js>, 19.99); 628 * <jc>// Returns: "Price: $19.99"</jc> 629 * 630 * <jc>// MessageFormat-style formatting</jc> 631 * f(<js>"Hello {0}, you have {1} items"</js>, <js>"John"</js>, 5); 632 * <jc>// Returns: "Hello John, you have 5 items"</jc> 633 * 634 * <jc>// Un-numbered MessageFormat placeholders (sequential)</jc> 635 * f(<js>"Hello {}, you have {} items"</js>, <js>"John"</js>, 5); 636 * <jc>// Returns: "Hello John, you have 5 items"</jc> 637 * 638 * <jc>// Mixed format styles in the same pattern</jc> 639 * f(<js>"User {0} has %d items and %s status"</js>, <js>"Alice"</js>, 10, <js>"active"</js>); 640 * <jc>// Returns: "User Alice has 10 items and active status"</jc> 641 * </p> 642 * 643 * @param pattern The format string supporting both MessageFormat and printf-style placeholders. 644 * @param args The arguments to format. 645 * @return The formatted string. 646 * @see StringUtils#format(String, Object...) 647 * @see StringFormat for detailed format specification 648 * @see StringUtils#format(String, Object...) for formatting details 649 */ 650 public static String f(String pattern, Object...args) { 651 return format(pattern, args); 652 } 653 654 /** 655 * Returns the first non-null value in the specified array. 656 * 657 * <p> 658 * This method iterates through the provided values and returns the first one that is not <jk>null</jk>. 659 * Useful for providing default values or selecting the first available option. 660 * 661 * <h5 class='section'>Example:</h5> 662 * <p class='bjava'> 663 * firstNonNull(<jk>null</jk>, <jk>null</jk>, <js>"Hello"</js>, <js>"World"</js>); <jc>// "Hello"</jc> 664 * firstNonNull(<js>"Hello"</js>, <js>"World"</js>); <jc>// "Hello"</jc> 665 * firstNonNull(<jk>null</jk>, <jk>null</jk>); <jc>// null</jc> 666 * firstNonNull(); <jc>// null</jc> 667 * </p> 668 * 669 * @param <T> The value types. 670 * @param t The values to check. 671 * @return The first non-null value, or <jk>null</jk> if the array is null or empty or contains only <jk>null</jk> values. 672 * @see StringUtils#firstNonEmpty(String...) 673 * @see StringUtils#firstNonBlank(String...) 674 */ 675 @SafeVarargs 676 public static <T> T firstNonNull(T...t) { 677 if (nn(t)) 678 for (var tt : t) 679 if (nn(tt)) 680 return tt; 681 return null; 682 } 683 684 /** 685 * Shortcut for calling {@link #firstNonNull(Object...)}. 686 * 687 * <p> 688 * Returns the first non-null value in the specified array. 689 * 690 * <h5 class='section'>Example:</h5> 691 * <p class='bjava'> 692 * or(<jk>null</jk>, <jk>null</jk>, <js>"Hello"</js>, <js>"World"</js>); <jc>// "Hello"</jc> 693 * or(<js>"Hello"</js>, <js>"World"</js>); <jc>// "Hello"</jc> 694 * or(<jk>null</jk>, <jk>null</jk>); <jc>// null</jc> 695 * </p> 696 * 697 * @param <T> The value types. 698 * @param t The values to check. 699 * @return The first non-null value, or <jk>null</jk> if all are <jk>null</jk>. 700 * @see #firstNonNull(Object...) 701 */ 702 @SafeVarargs 703 public static <T> T or(T...t) { 704 return firstNonNull(t); 705 } 706 707 /** 708 * Returns the specified value if not null, otherwise returns the default value. 709 * 710 * <p> 711 * This is a null-safe way to provide default values. 712 * 713 * <h5 class='section'>Example:</h5> 714 * <p class='bjava'> 715 * def(<js>"Hello"</js>, <js>"World"</js>); <jc>// "Hello"</jc> 716 * def(<jk>null</jk>, <js>"World"</js>); <jc>// "World"</jc> 717 * </p> 718 * 719 * @param <T> The value type. 720 * @param value The value to check. 721 * @param defaultValue The default value to return if <c>value</c> is <jk>null</jk>. 722 * @return The value if not null, otherwise the default value. 723 */ 724 public static <T> T def(T value, T defaultValue) { 725 return nn(value) ? value : defaultValue; 726 } 727 728 /** 729 * Returns <jk>true</jk> if all specified boolean values are <jk>true</jk>. 730 * 731 * <p> 732 * Returns <jk>true</jk> if the array is empty (vacuous truth). 733 * 734 * <h5 class='section'>Example:</h5> 735 * <p class='bjava'> 736 * and(<jk>true</jk>, <jk>true</jk>, <jk>true</jk>); <jc>// true</jc> 737 * and(<jk>true</jk>, <jk>false</jk>, <jk>true</jk>); <jc>// false</jc> 738 * and(); <jc>// true (empty array)</jc> 739 * </p> 740 * 741 * @param values The boolean values to test. 742 * @return <jk>true</jk> if all values are <jk>true</jk>. 743 */ 744 @SafeVarargs 745 public static boolean and(boolean...values) { 746 if (values == null || values.length == 0) 747 return true; 748 for (boolean v : values) 749 if (! v) 750 return false; 751 return true; 752 } 753 754 /** 755 * Returns <jk>true</jk> if any of the specified boolean values are <jk>true</jk>. 756 * 757 * <p> 758 * Returns <jk>false</jk> if the array is empty. 759 * 760 * <h5 class='section'>Example:</h5> 761 * <p class='bjava'> 762 * or(<jk>true</jk>, <jk>false</jk>, <jk>false</jk>); <jc>// true</jc> 763 * or(<jk>false</jk>, <jk>false</jk>, <jk>false</jk>); <jc>// false</jc> 764 * or(); <jc>// false (empty array)</jc> 765 * </p> 766 * 767 * @param values The boolean values to test. 768 * @return <jk>true</jk> if any value is <jk>true</jk>. 769 */ 770 @SafeVarargs 771 public static boolean or(boolean...values) { 772 if (values == null || values.length == 0) 773 return false; 774 for (boolean v : values) 775 if (v) 776 return true; 777 return false; 778 } 779 780 /** 781 * Returns the logical negation of the specified boolean value. 782 * 783 * <h5 class='section'>Example:</h5> 784 * <p class='bjava'> 785 * not(<jk>true</jk>); <jc>// false</jc> 786 * not(<jk>false</jk>); <jc>// true</jc> 787 * </p> 788 * 789 * @param value The boolean value to negate. 790 * @return The negated value. 791 */ 792 public static boolean not(boolean value) { 793 return ! value; 794 } 795 796 /** 797 * Returns the minimum of two comparable values. 798 * 799 * <h5 class='section'>Example:</h5> 800 * <p class='bjava'> 801 * min(5, 10); <jc>// 5</jc> 802 * min(<js>"apple"</js>, <js>"banana"</js>); <jc>// "apple"</jc> 803 * </p> 804 * 805 * @param <T> The comparable type. 806 * @param o1 Value 1. 807 * @param o2 Value 2. 808 * @return The minimum value. 809 */ 810 public static <T extends Comparable<T>> T min(T o1, T o2) { 811 if (o1 == null) return o2; 812 if (o2 == null) return o1; 813 return o1.compareTo(o2) <= 0 ? o1 : o2; 814 } 815 816 /** 817 * Returns the maximum of two comparable values. 818 * 819 * <h5 class='section'>Example:</h5> 820 * <p class='bjava'> 821 * max(5, 10); <jc>// 10</jc> 822 * max(<js>"apple"</js>, <js>"banana"</js>); <jc>// "banana"</jc> 823 * </p> 824 * 825 * @param <T> The comparable type. 826 * @param o1 Value 1. 827 * @param o2 Value 2. 828 * @return The maximum value. 829 */ 830 public static <T extends Comparable<T>> T max(T o1, T o2) { 831 if (o1 == null) return o2; 832 if (o2 == null) return o1; 833 return o1.compareTo(o2) >= 0 ? o1 : o2; 834 } 835 836 /** 837 * Returns the absolute value of the specified number. 838 * 839 * <h5 class='section'>Example:</h5> 840 * <p class='bjava'> 841 * abs(-5); <jc>// 5</jc> 842 * abs(5); <jc>// 5</jc> 843 * abs(-3.14); <jc>// 3.14</jc> 844 * </p> 845 * 846 * @param <T> The number type. 847 * @param value The number. 848 * @return The absolute value. 849 */ 850 @SuppressWarnings("unchecked") 851 public static <T extends Number> T abs(T value) { 852 if (value == null) 853 return null; 854 if (value instanceof Integer) 855 return (T)Integer.valueOf(Math.abs(value.intValue())); 856 if (value instanceof Long) 857 return (T)Long.valueOf(Math.abs(value.longValue())); 858 if (value instanceof Double) 859 return (T)Double.valueOf(Math.abs(value.doubleValue())); 860 if (value instanceof Float) 861 return (T)Float.valueOf(Math.abs(value.floatValue())); 862 if (value instanceof Short) 863 return (T)Short.valueOf((short)Math.abs(value.shortValue())); 864 if (value instanceof Byte) 865 return (T)Byte.valueOf((byte)Math.abs(value.byteValue())); 866 // For other Number types, use double 867 return (T)Double.valueOf(Math.abs(value.doubleValue())); 868 } 869 870 /** 871 * Creates a formatted string supplier with format arguments for lazy evaluation. 872 * 873 * <p>This method returns a {@link Supplier} that formats the string pattern with the provided arguments 874 * only when the supplier's {@code get()} method is called. This is useful for expensive string formatting 875 * operations that may not always be needed, such as error messages in assertions.</p> 876 * 877 * <p> 878 * Supports both MessageFormat-style and printf-style formatting in the same pattern. 879 * Also supports un-numbered MessageFormat placeholders: <js>"{}"</js> - Sequential placeholders that are automatically numbered. 880 * See {@link #f(String, Object...)} for format specification details. 881 * </p> 882 * 883 * <h5 class='section'>Usage Examples:</h5> 884 * <p class='bjava'> 885 * <jc>// Lazy evaluation - string is only formatted if assertion fails</jc> 886 * assertTrue(condition, fs(<js>"Expected %s but got %s"</js>, expected, actual)); 887 * 888 * <jc>// Can be used anywhere a Supplier<String> is expected</jc> 889 * Supplier<String> <jv>messageSupplier</jv> = fs(<js>"Processing item %d of %d"</js>, i, total); 890 * 891 * <jc>// Mixed format styles</jc> 892 * Supplier<String> <jv>msg</jv> = fs(<js>"User {0} has %d items"</js>, <js>"Alice"</js>, 10); 893 * 894 * <jc>// Un-numbered MessageFormat placeholders</jc> 895 * Supplier<String> <jv>msg2</jv> = fs(<js>"Hello {}, you have {} items"</js>, <js>"John"</js>, 5); 896 * </p> 897 * 898 * @param pattern The format string supporting both MessageFormat and printf-style placeholders 899 * (e.g., <js>"{0}"</js>, <js>"%s"</js>, <js>"%d"</js>, etc.). 900 * @param args The arguments to substitute into the pattern placeholders. 901 * @return A {@link Supplier} that will format the string when {@code get()} is called. 902 * @see StringUtils#format(String, Object...) 903 * @see #f(String, Object...) for format specification details 904 * @see StringUtils#format(String, Object...) for formatting details 905 */ 906 public static Supplier<String> fs(String pattern, Object...args) { 907 return () -> format(pattern, args); 908 } 909 910 /** 911 * Calculates a hash code for the specified values. 912 * 913 * <p> 914 * This method delegates to {@link HashCode#of(Object...)} to combine multiple values into a single hash code. 915 * It uses the same algorithm as {@link Objects#hash(Object...)} (31 * result + element hash). 916 * 917 * <p> 918 * Special handling is provided for: 919 * <ul> 920 * <li><b>Annotations:</b> Uses {@link org.apache.juneau.commons.utils.AnnotationUtils#hash(java.lang.annotation.Annotation)} to ensure consistent hashing 921 * according to the {@link java.lang.annotation.Annotation#hashCode()} contract. 922 * <li><b>Arrays:</b> Uses content-based hashing via {@link java.util.Arrays#hashCode(Object[])} 923 * instead of identity-based hashing. 924 * <li><b>Null values:</b> Treated as 0 in the hash calculation. 925 * </ul> 926 * 927 * <h5 class='section'>Example:</h5> 928 * <p class='bjava'> 929 * <jc>// Hash multiple values</jc> 930 * <jk>int</jk> <jv>hash1</jv> = h(<js>"Hello"</js>, 123, <jk>true</jk>); 931 * 932 * <jc>// Hash with annotations</jc> 933 * <jk>int</jk> <jv>hash2</jv> = h(<jv>myAnnotation</jv>, <js>"value"</js>); 934 * 935 * <jc>// Hash with arrays (content-based)</jc> 936 * <jk>int</jk> <jv>hash3</jv> = h(<jk>new</jk> <jk>int</jk>[]{1, 2, 3}); 937 * 938 * <jc>// Use in hashCode() implementation</jc> 939 * <jk>public</jk> <jk>int</jk> hashCode() { 940 * <jk>return</jk> h(id, name, created); 941 * } 942 * </p> 943 * 944 * @param values The values to hash. 945 * @return A hash code value for the given values. 946 * @see HashCode#of(Object...) 947 * @see org.apache.juneau.commons.utils.AnnotationUtils#hash(java.lang.annotation.Annotation) 948 * @see Objects#hash(Object...) 949 */ 950 public static final int h(Object...values) { 951 assertArgNotNull("values", values); 952 return HashCode.of(values); 953 } 954 955 /** 956 * Converts the specified object into an identifiable string of the form "Class[identityHashCode]" 957 * @param o The object to convert to a string. 958 * @return An identity string. 959 */ 960 public static String id(Object o) { 961 if (o instanceof Optional<?> opt) 962 o = opt.orElse(null); 963 if (o == null) 964 return null; 965 return cnsq(o) + "@" + System.identityHashCode(o); 966 } 967 968 /** 969 * Checks if the specified object is an array. 970 * 971 * <p> 972 * This method checks if the object is not <jk>null</jk> and its class represents an array type 973 * (primitive arrays or object arrays). 974 * 975 * <h5 class='section'>Example:</h5> 976 * <p class='bjava'> 977 * isArray(<jk>new</jk> <jk>int</jk>[]{1, 2, 3}); <jc>// true</jc> 978 * isArray(<jk>new</jk> String[]{"a", "b"}); <jc>// true</jc> 979 * isArray(<js>"Hello"</js>); <jc>// false</jc> 980 * isArray(<jk>null</jk>); <jc>// false</jc> 981 * </p> 982 * 983 * @param o The object to check. 984 * @return <jk>true</jk> if the object is not <jk>null</jk> and is an array. 985 * @see Class#isArray() 986 */ 987 public static boolean isArray(Object o) { 988 return nn(o) && o.getClass().isArray(); 989 } 990 991 /** 992 * Returns <jk>true</jk> if the specified number is inclusively between the two values. 993 * 994 * @param n The number to check. 995 * @param lower The lower bound (inclusive). 996 * @param higher The upper bound (inclusive). 997 * @return <jk>true</jk> if the number is between the bounds. 998 */ 999 public static boolean isBetween(int n, int lower, int higher) { 1000 return n >= lower && n <= higher; 1001 } 1002 1003 /** 1004 * Checks if a string is empty (null or zero length). 1005 * 1006 * <h5 class='section'>Example:</h5> 1007 * <p class='bjava'> 1008 * e(<jk>null</jk>); <jc>// true</jc> 1009 * e(<js>""</js>); <jc>// true</jc> 1010 * e(<js>" "</js>); <jc>// false</jc> 1011 * e(<js>"hello"</js>); <jc>// false</jc> 1012 * </p> 1013 * 1014 * @param str The string to check. 1015 * @return <jk>true</jk> if the string is null or has zero length. 1016 */ 1017 public static boolean e(CharSequence str) { 1018 return str == null || str.isEmpty(); 1019 } 1020 1021 /** 1022 * Checks if the specified collection is <jk>null</jk> or empty. 1023 * 1024 * <p> 1025 * This is a null-safe operation. Returns <jk>true</jk> if the collection is <jk>null</jk> or 1026 * has no elements. 1027 * 1028 * <h5 class='section'>Example:</h5> 1029 * <p class='bjava'> 1030 * e(<jk>null</jk>); <jc>// true</jc> 1031 * e(Collections.emptyList()); <jc>// true</jc> 1032 * e(Arrays.asList(1, 2, 3)); <jc>// false</jc> 1033 * </p> 1034 * 1035 * @param o The collection to check. 1036 * @return <jk>true</jk> if the specified collection is <jk>null</jk> or empty. 1037 * @see #ne(Collection) 1038 * @see Collection#isEmpty() 1039 */ 1040 public static boolean e(Collection<?> o) { 1041 if (o == null) 1042 return true; 1043 return o.isEmpty(); 1044 } 1045 1046 /** 1047 * Checks if the specified map is <jk>null</jk> or empty. 1048 * 1049 * <p> 1050 * This is a null-safe operation. Returns <jk>true</jk> if the map is <jk>null</jk> or 1051 * has no key-value mappings. 1052 * 1053 * <h5 class='section'>Example:</h5> 1054 * <p class='bjava'> 1055 * e(<jk>null</jk>); <jc>// true</jc> 1056 * e(Collections.emptyMap()); <jc>// true</jc> 1057 * e(Map.of(<js>"key"</js>, <js>"value"</js>)); <jc>// false</jc> 1058 * </p> 1059 * 1060 * @param o The map to check. 1061 * @return <jk>true</jk> if the specified map is <jk>null</jk> or empty. 1062 * @see #ne(Map) 1063 * @see Map#isEmpty() 1064 */ 1065 public static boolean e(Map<?,?> o) { 1066 if (o == null) 1067 return true; 1068 return o.isEmpty(); 1069 } 1070 1071 /** 1072 * Returns <jk>true</jk> if the specified object is empty. 1073 * 1074 * <p> 1075 * Return <jk>true</jk> if the value is any of the following: 1076 * <ul> 1077 * <li><jk>null</jk> 1078 * <li>An empty Collection 1079 * <li>An empty Map 1080 * <li>An empty array 1081 * <li>An empty CharSequence 1082 * <li>An empty String when serialized to a string using {@link Object#toString()}. 1083 * </ul> 1084 * 1085 * @param o The object to test. 1086 * @return <jk>true</jk> if the specified object is empty. 1087 */ 1088 public static boolean e(Object o) { 1089 if (o == null) 1090 return true; 1091 if (o instanceof Collection<?> o2) 1092 return o2.isEmpty(); 1093 if (o instanceof Map<?,?> o2) 1094 return o2.isEmpty(); 1095 if (isArray(o)) 1096 return (Array.getLength(o) == 0); 1097 return o.toString().isEmpty(); 1098 } 1099 1100 /** 1101 * Checks if the specified string is not <jk>null</jk> and not empty. 1102 * 1103 * <p> 1104 * This is the inverse of {@link #e(CharSequence)}. 1105 * Note: This method does not check for blank strings (whitespace-only strings). 1106 * 1107 * <h5 class='section'>Example:</h5> 1108 * <p class='bjava'> 1109 * ne(<js>"Hello"</js>); <jc>// true</jc> 1110 * ne(<js>" "</js>); <jc>// true (whitespace is not empty)</jc> 1111 * ne(<jk>null</jk>); <jc>// false</jc> 1112 * ne(<js>""</js>); <jc>// false</jc> 1113 * </p> 1114 * 1115 * @param o The string to check. 1116 * @return <jk>true</jk> if string is not <jk>null</jk> and not empty. 1117 * @see #e(CharSequence) 1118 * @see StringUtils#isNotBlank(String) 1119 */ 1120 public static boolean ne(CharSequence o) { 1121 return ! e(o); 1122 } 1123 1124 /** 1125 * Checks if the specified collection is not <jk>null</jk> and not empty. 1126 * 1127 * <p> 1128 * This is the inverse of {@link #e(Collection)}. 1129 * 1130 * <h5 class='section'>Example:</h5> 1131 * <p class='bjava'> 1132 * ne(Arrays.asList(1, 2, 3)); <jc>// true</jc> 1133 * ne(<jk>null</jk>); <jc>// false</jc> 1134 * ne(Collections.emptyList()); <jc>// false</jc> 1135 * </p> 1136 * 1137 * @param value The collection to check. 1138 * @return <jk>true</jk> if the specified collection is not <jk>null</jk> and not empty. 1139 * @see #e(Collection) 1140 */ 1141 public static boolean ne(Collection<?> value) { 1142 return ! e(value); 1143 } 1144 1145 /** 1146 * Checks if the specified map is not <jk>null</jk> and not empty. 1147 * 1148 * <p> 1149 * This is the inverse of {@link #e(Map)}. 1150 * 1151 * <h5 class='section'>Example:</h5> 1152 * <p class='bjava'> 1153 * ne(Map.of(<js>"key"</js>, <js>"value"</js>)); <jc>// true</jc> 1154 * ne(<jk>null</jk>); <jc>// false</jc> 1155 * ne(Collections.emptyMap()); <jc>// false</jc> 1156 * </p> 1157 * 1158 * @param value The map to check. 1159 * @return <jk>true</jk> if the specified map is not <jk>null</jk> and not empty. 1160 * @see #e(Map) 1161 */ 1162 public static boolean ne(Map<?,?> value) { 1163 return ! e(value); 1164 } 1165 1166 /** 1167 * Checks if the specified object is not <jk>null</jk> and not empty. 1168 * 1169 * <p> 1170 * This method works on any of the following data types: 1171 * <ul> 1172 * <li>String, CharSequence - checks if length > 0</li> 1173 * <li>Collection - checks if not empty</li> 1174 * <li>Map - checks if not empty</li> 1175 * <li>Array - checks if length > 0</li> 1176 * <li>All other types - converts to string and checks if not empty</li> 1177 * </ul> 1178 * 1179 * <h5 class='section'>Example:</h5> 1180 * <p class='bjava'> 1181 * ne(<js>"Hello"</js>); <jc>// true</jc> 1182 * ne(Arrays.asList(1, 2)); <jc>// true</jc> 1183 * ne(Map.of(<js>"key"</js>, <js>"value"</js>)); <jc>// true</jc> 1184 * ne(<jk>null</jk>); <jc>// false</jc> 1185 * ne(<js>""</js>); <jc>// false</jc> 1186 * ne(Collections.emptyList()); <jc>// false</jc> 1187 * </p> 1188 * 1189 * @param value The value being checked. 1190 * @return <jk>true</jk> if the specified object is not <jk>null</jk> and not empty. 1191 * @see #e(Object) 1192 */ 1193 public static boolean ne(Object value) { 1194 if (value == null) 1195 return false; 1196 if (value instanceof CharSequence value2) 1197 return ! value2.isEmpty(); 1198 if (value instanceof Collection<?> value2) 1199 return ! value2.isEmpty(); 1200 if (value instanceof Map<?,?> value2) 1201 return ! value2.isEmpty(); 1202 if (isArray(value)) 1203 return Array.getLength(value) > 0; 1204 return ne(s(value)); 1205 } 1206 1207 /** 1208 * Checks if the specified number is not <jk>null</jk> and not <c>-1</c>. 1209 * 1210 * <p> 1211 * This method is commonly used to check if a numeric value represents a valid index or ID, 1212 * where <c>-1</c> is often used as a sentinel value to indicate "not found" or "invalid". 1213 * 1214 * <h5 class='section'>Example:</h5> 1215 * <p class='bjava'> 1216 * nm1(5); <jc>// true</jc> 1217 * nm1(0); <jc>// true</jc> 1218 * nm1(-1); <jc>// false</jc> 1219 * nm1(<jk>null</jk>); <jc>// false</jc> 1220 * </p> 1221 * 1222 * @param <T> The value types. 1223 * @param value The value being checked. 1224 * @return <jk>true</jk> if the specified number is not <jk>null</jk> and not <c>-1</c>. 1225 */ 1226 public static <T extends Number> boolean nm1(T value) { 1227 return nn(value) && value.intValue() != -1; 1228 } 1229 1230 /** 1231 * Returns <jk>true</jk> if the specified object is <jk>null</jk>. 1232 * 1233 * <p> 1234 * Equivalent to <c><jv>value</jv> == <jk>null</jk></c>, but with a more readable method name. 1235 * 1236 * <h5 class='section'>Example:</h5> 1237 * <p class='bjava'> 1238 * n(<jk>null</jk>); <jc>// true</jc> 1239 * n(<js>"Hello"</js>); <jc>// false</jc> 1240 * n(123); <jc>// false</jc> 1241 * </p> 1242 * 1243 * @param <T> The object type. 1244 * @param value The object to check. 1245 * @return <jk>true</jk> if the specified object is <jk>null</jk>. 1246 * @see #nn(Object) 1247 */ 1248 public static <T> boolean n(T value) { 1249 return value == null; 1250 } 1251 1252 /** 1253 * Returns <jk>true</jk> if all specified values are <jk>null</jk>. 1254 * 1255 * <p> 1256 * If the values array itself is <jk>null</jk>, returns <jk>true</jk>. 1257 * If any value in the array is not <jk>null</jk>, returns <jk>false</jk>. 1258 * 1259 * <h5 class='section'>Example:</h5> 1260 * <p class='bjava'> 1261 * <jk>boolean</jk> <jv>allNull</jv> = <jsm>n</jsm>(<jk>null</jk>, <jk>null</jk>, <jk>null</jk>); <jc>// true</jc> 1262 * <jk>boolean</jk> <jv>notAllNull</jv> = <jsm>n</jsm>(<jk>null</jk>, <js>"value"</js>, <jk>null</jk>); <jc>// false</jc> 1263 * </p> 1264 * 1265 * @param values The values to check. 1266 * @return <jk>true</jk> if all values are <jk>null</jk> (or the array is <jk>null</jk>), <jk>false</jk> otherwise. 1267 */ 1268 public static boolean n(Object...values) { 1269 if (values == null) return true; 1270 for (var v : values) 1271 if (v != null) 1272 return false; 1273 return true; 1274 } 1275 1276 /** 1277 * Checks if the specified Boolean is not <jk>null</jk> and is <jk>true</jk>. 1278 * 1279 * <p> 1280 * This is a null-safe way to check if a Boolean wrapper is true. Returns <jk>false</jk> if 1281 * the value is <jk>null</jk> or <jk>false</jk>. 1282 * 1283 * <h5 class='section'>Example:</h5> 1284 * <p class='bjava'> 1285 * isTrue(<jk>true</jk>); <jc>// true</jc> 1286 * isTrue(<jk>false</jk>); <jc>// false</jc> 1287 * isTrue(<jk>null</jk>); <jc>// false</jc> 1288 * </p> 1289 * 1290 * @param value The value being checked. 1291 * @return <jk>true</jk> if the specified boolean is not <jk>null</jk> and is <jk>true</jk>. 1292 */ 1293 public static boolean isTrue(Boolean value) { 1294 return nn(value) && value; 1295 } 1296 1297 /** 1298 * Convenience method for calling {@link StringUtils#lowerCase(String)}. 1299 * 1300 * <p> 1301 * Converts the string to lowercase if not null. 1302 * 1303 * @param value The string to convert. 1304 * @return The lowercase string, or <jk>null</jk> if the input was <jk>null</jk>. 1305 */ 1306 public static String lc(String value) { 1307 return StringUtils.lowerCase(value); 1308 } 1309 1310 /** 1311 * Creates a thread-safe memoizing supplier that computes a value once and caches it. 1312 * 1313 * <p> 1314 * The returned supplier is thread-safe and guarantees that the underlying supplier's {@link Supplier#get() get()} 1315 * method is called at most once, even under concurrent access. The computed value is cached and returned 1316 * on all subsequent calls. 1317 * 1318 * <p> 1319 * This is useful for lazy initialization of expensive-to-compute values that should only be calculated once. 1320 * 1321 * <h5 class='section'>Example:</h5> 1322 * <p class='bjava'> 1323 * <jc>// Create a memoizing supplier</jc> 1324 * Supplier<ExpensiveObject> <jv>supplier</jv> = mem(() -> <jk>new</jk> ExpensiveObject()); 1325 * 1326 * <jc>// First call computes and caches the value</jc> 1327 * ExpensiveObject <jv>obj1</jv> = <jv>supplier</jv>.get(); 1328 * 1329 * <jc>// Subsequent calls return the cached value (no recomputation)</jc> 1330 * ExpensiveObject <jv>obj2</jv> = <jv>supplier</jv>.get(); <jc>// Same instance as obj1</jc> 1331 * </p> 1332 * 1333 * <h5 class='section'>Thread Safety:</h5> 1334 * <p> 1335 * The implementation uses {@link java.util.concurrent.atomic.AtomicReference} with double-checked locking 1336 * to ensure thread-safe lazy initialization. Under high contention, multiple threads may compute the value, 1337 * but only one result is stored and returned to all callers. 1338 * 1339 * <h5 class='section'>Notes:</h5> 1340 * <ul> 1341 * <li>The supplier may be called multiple times if threads race, but only one result is cached. 1342 * <li>The cached value can be <jk>null</jk> if the supplier returns <jk>null</jk>. 1343 * <li>Once cached, the value never changes (immutable after first computation). 1344 * <li>The returned supplier does not support {@link #toString()}, {@link #equals(Object)}, or {@link #hashCode()}. 1345 * </ul> 1346 * 1347 * @param <T> The type of value supplied. 1348 * @param supplier The supplier to memoize. Must not be <jk>null</jk>. 1349 * @return A thread-safe memoizing wrapper around the supplier. 1350 * @throws NullPointerException if supplier is <jk>null</jk>. 1351 */ 1352 public static <T> OptionalSupplier<T> mem(Supplier<T> supplier) { 1353 assertArgNotNull("supplier", supplier); 1354 1355 var cache = new AtomicReference<Optional<T>>(); 1356 1357 return () -> { 1358 var h = cache.get(); 1359 if (h == null) { 1360 h = opt(supplier.get()); 1361 if (! cache.compareAndSet(null, h)) { 1362 // Another thread beat us, use their value 1363 h = cache.get(); 1364 } 1365 } 1366 return h.orElse(null); 1367 }; 1368 } 1369 1370 /** 1371 * Creates a resettable memoizing supplier that caches the result of the first call and optionally allows resetting. 1372 * 1373 * <p> 1374 * This is similar to {@link #mem(Supplier)}, but returns a {@link ResettableSupplier} that supports 1375 * clearing the cached value, forcing recomputation on the next call. 1376 * 1377 * <h5 class='section'>Usage:</h5> 1378 * <p class='bjava'> 1379 * ResettableSupplier<String> <jv>supplier</jv> = Utils.<jsm>memr</jsm>(() -> expensiveComputation()); 1380 * 1381 * <jc>// First call computes and caches</jc> 1382 * String <jv>result1</jv> = <jv>supplier</jv>.get(); 1383 * 1384 * <jc>// Subsequent calls return cached value</jc> 1385 * String <jv>result2</jv> = <jv>supplier</jv>.get(); 1386 * 1387 * <jc>// Reset forces recomputation on next get()</jc> 1388 * <jv>supplier</jv>.reset(); 1389 * String <jv>result3</jv> = <jv>supplier</jv>.get(); <jc>// Recomputes</jc> 1390 * </p> 1391 * 1392 * <h5 class='section'>Thread Safety:</h5> 1393 * <p> 1394 * The returned supplier is thread-safe for both {@link ResettableSupplier#get()} and 1395 * {@link ResettableSupplier#reset()} operations. If multiple threads call get() simultaneously 1396 * after a reset, the supplier may be invoked multiple times, but only one result will be cached. 1397 * 1398 * <h5 class='section'>See Also:</h5> 1399 * <ul> 1400 * <li class='jc'>{@link ResettableSupplier} 1401 * </ul> 1402 * 1403 * @param <T> The type of value supplied. 1404 * @param supplier The supplier to memoize. Must not be <jk>null</jk>. 1405 * @return A thread-safe resettable memoizing wrapper around the supplier. 1406 * @throws NullPointerException if supplier is <jk>null</jk>. 1407 */ 1408 public static <T> ResettableSupplier<T> memr(Supplier<T> supplier) { 1409 assertArgNotNull("supplier", supplier); 1410 return new ResettableSupplier<>(supplier); 1411 } 1412 1413 /** 1414 * Returns <jk>null</jk> for the specified type. 1415 * 1416 * <p> 1417 * This is a convenience method that allows you to explicitly return <jk>null</jk> with a type 1418 * parameter, which can help with type inference in some contexts. 1419 * 1420 * <h5 class='section'>Example:</h5> 1421 * <p class='bjava'> 1422 * String <jv>result</jv> = n(String.<jk>class</jk>); <jc>// null</jc> 1423 * List<String> <jv>list</jv> = n(List.<jk>class</jk>); <jc>// null</jc> 1424 * </p> 1425 * 1426 * @param <T> The type. 1427 * @param type The type class (unused, but helps with type inference). 1428 * @return <jk>null</jk>. 1429 */ 1430 public static <T> T no(Class<T> type) { 1431 return null; 1432 } 1433 1434 /** 1435 * Null-safe not-equals check. 1436 * 1437 * <p> 1438 * This is the inverse of {@link #eq(Object, Object)}. Returns <jk>true</jk> if the objects 1439 * are not equal, handling <jk>null</jk> values gracefully. 1440 * 1441 * <h5 class='section'>Example:</h5> 1442 * <p class='bjava'> 1443 * ne(<js>"Hello"</js>, <js>"World"</js>); <jc>// true</jc> 1444 * ne(<js>"Hello"</js>, <js>"Hello"</js>); <jc>// false</jc> 1445 * ne(<jk>null</jk>, <jk>null</jk>); <jc>// false</jc> 1446 * ne(<js>"Hello"</js>, <jk>null</jk>); <jc>// true</jc> 1447 * </p> 1448 * 1449 * @param <T> The object type. 1450 * @param s1 Object 1. 1451 * @param s2 Object 2. 1452 * @return <jk>true</jk> if the objects are not equal. 1453 * @see #eq(Object, Object) 1454 */ 1455 // TODO - Rename this to neq, then add a ne for not-empty 1456 public static <T> boolean neq(T s1, T s2) { 1457 return ! eq(s1, s2); 1458 } 1459 1460 /** 1461 * Tests two objects for inequality using a custom predicate, gracefully handling nulls. 1462 * 1463 * <p> 1464 * This is the inverse of {@link #eq(Object, Object, BiPredicate)}. The predicate is only called 1465 * if both objects are non-null and not the same reference. 1466 * 1467 * <h5 class='section'>Example:</h5> 1468 * <p class='bjava'> 1469 * Role <jv>r1</jv> = <jk>new</jk> Role(1, <js>"admin"</js>); 1470 * Role <jv>r2</jv> = <jk>new</jk> Role(2, <js>"user"</js>); 1471 * ne(<jv>r1</jv>, <jv>r2</jv>, (x,y) -> x.id == y.id); <jc>// true (different IDs)</jc> 1472 * </p> 1473 * 1474 * @param <T> Object 1 type. 1475 * @param <U> Object 2 type. 1476 * @param o1 Object 1. 1477 * @param o2 Object 2. 1478 * @param test The predicate to use for equality testing (only called if both objects are non-null and different references). 1479 * @return <jk>true</jk> if the objects are not equal based on the test, or if one is <jk>null</jk> and the other is not. 1480 * @see #eq(Object, Object, BiPredicate) 1481 */ 1482 // TODO - Rename this to neq, then add a ne for not-empty 1483 public static <T,U> boolean neq(T o1, U o2, BiPredicate<T,U> test) { 1484 if (o1 == null) 1485 return nn(o2); 1486 if (o2 == null) 1487 return true; 1488 if (o1 == o2) 1489 return false; 1490 return ! test.test(o1, o2); 1491 } 1492 1493 /** 1494 * Tests two strings for non-equality ignoring case, but gracefully handles nulls. 1495 * 1496 * <p> 1497 * This is the inverse of {@link #eqic(String, String)}. 1498 * 1499 * <h5 class='section'>Example:</h5> 1500 * <p class='bjava'> 1501 * neic(<js>"Hello"</js>, <js>"World"</js>); <jc>// true</jc> 1502 * neic(<js>"Hello"</js>, <js>"hello"</js>); <jc>// false (equal ignoring case)</jc> 1503 * neic(<jk>null</jk>, <jk>null</jk>); <jc>// false (both null)</jc> 1504 * neic(<js>"Hello"</js>, <jk>null</jk>); <jc>// true</jc> 1505 * </p> 1506 * 1507 * @param s1 String 1. 1508 * @param s2 String 2. 1509 * @return <jk>true</jk> if the strings are not equal ignoring case. 1510 * @see #eqic(String, String) 1511 */ 1512 // TODO - Rename this to neqic, then add a ne for not-empty 1513 public static boolean neqic(String s1, String s2) { 1514 return ! eqic(s1, s2); 1515 } 1516 1517 /** 1518 * Returns <jk>true</jk> if the specified object is not <jk>null</jk>. 1519 * 1520 * <p> 1521 * Equivalent to <c><jv>o</jv> != <jk>null</jk></c>, but with a more readable method name. 1522 * 1523 * <h5 class='section'>Example:</h5> 1524 * <p class='bjava'> 1525 * <jk>import static</jk> org.apache.juneau.commons.utils.Utils.*; 1526 * 1527 * <jk>if</jk> (<jsm>nn</jsm>(<jv>myObject</jv>)) { 1528 * <jc>// Do something with non-null object</jc> 1529 * } 1530 * </p> 1531 * 1532 * @param o The object to check. 1533 * @return <jk>true</jk> if the specified object is not <jk>null</jk>. 1534 */ 1535 public static boolean nn(Object o) { 1536 return o != null; 1537 } 1538 1539 /** 1540 * Shortcut for calling {@link Optional#ofNullable(Object)}. 1541 * 1542 * <p> 1543 * This is a convenience method that provides a shorter name for wrapping objects in an Optional. 1544 * 1545 * <h5 class='section'>Example:</h5> 1546 * <p class='bjava'> 1547 * Optional<String> <jv>opt1</jv> = opt(<js>"Hello"</js>); <jc>// Optional.of("Hello")</jc> 1548 * Optional<String> <jv>opt2</jv> = opt(<jk>null</jk>); <jc>// Optional.empty()</jc> 1549 * </p> 1550 * 1551 * @param <T> The object type. 1552 * @param t The object to wrap in an Optional. 1553 * @return An Optional containing the specified object, or empty if <jk>null</jk>. 1554 * @see Optional#ofNullable(Object) 1555 * @see #opte() 1556 */ 1557 public static final <T> Optional<T> opt(T t) { 1558 return Optional.ofNullable(t); 1559 } 1560 1561 /** 1562 * Returns an empty Optional. 1563 * 1564 * <p> 1565 * This is a convenience method that provides a shorter name for creating an empty Optional. 1566 * 1567 * <h5 class='section'>Example:</h5> 1568 * <p class='bjava'> 1569 * Optional<String> <jv>empty</jv> = opte(); <jc>// Optional.empty()</jc> 1570 * </p> 1571 * 1572 * @param <T> The object type. 1573 * @return An empty Optional. 1574 * @see Optional#empty() 1575 * @see #opt(Object) 1576 */ 1577 public static final <T> Optional<T> opte() { 1578 return Optional.empty(); 1579 } 1580 1581 /** 1582 * Prints all the specified lines to System.out with line numbers. 1583 * 1584 * <p> 1585 * Each line is printed with a 4-digit line number prefix (e.g., " 1:", " 2:", etc.). 1586 * This is useful for debugging or displaying formatted output. 1587 * 1588 * <h5 class='section'>Example:</h5> 1589 * <p class='bjava'> 1590 * printLines(<jk>new</jk> String[]{<js>"First line"</js>, <js>"Second line"</js>}); 1591 * <jc>// Output:</jc> 1592 * <jc>// 1:First line</jc> 1593 * <jc>// 2:Second line</jc> 1594 * </p> 1595 * 1596 * @param lines The lines to print. 1597 */ 1598 public static final void printLines(String[] lines) { 1599 for (var i = 0; i < lines.length; i++) 1600 System.out.println(String.format("%4s:" + lines[i], i + 1)); // NOSONAR - NOT DEBUG 1601 } 1602 1603 /** 1604 * Shortcut for calling {@link StringUtils#readable(Object)}. 1605 * 1606 * <p>Converts an arbitrary object to a readable string format suitable for debugging and testing. 1607 * 1608 * @param o The object to convert to readable format. Can be <jk>null</jk>. 1609 * @return A readable string representation of the object, or <jk>null</jk> if the input was <jk>null</jk>. 1610 * @see StringUtils#readable(Object) 1611 */ 1612 public static String r(Object o) { 1613 return readable(o); 1614 } 1615 1616 // TODO: Look for cases of getClass().getName() and getClass().getSimpleName() in the code and replace with cn() and scn(). 1617 // These utility methods provide cleaner, more concise syntax and null-safe handling. 1618 // Search patterns: 1619 // - Replace: getClass().getName() -> cn(this) or cn(object) 1620 // - Replace: getClass().getSimpleName() -> scn(this) or scn(object) 1621 // - Replace: obj.getClass().getName() -> cn(obj) 1622 // - Replace: obj.getClass().getSimpleName() -> scn(obj) 1623 1624 /** 1625 * Shortcut for converting an object to a string. 1626 * 1627 * <p> 1628 * This is a null-safe string conversion. Returns <jk>null</jk> if the object is <jk>null</jk>, 1629 * otherwise returns the result of calling {@link Object#toString()} on the object. 1630 * 1631 * <h5 class='section'>Example:</h5> 1632 * <p class='bjava'> 1633 * s(<js>"Hello"</js>); <jc>// "Hello"</jc> 1634 * s(123); <jc>// "123"</jc> 1635 * s(<jk>null</jk>); <jc>// null</jc> 1636 * </p> 1637 * 1638 * @param val The object to convert. 1639 * @return The string representation of the object, or <jk>null</jk> if the object is <jk>null</jk>. 1640 * @see Object#toString() 1641 * @see #emptyIfNull(Object) 1642 */ 1643 public static String s(Object val) { 1644 return val == null ? null : val.toString(); 1645 } 1646 1647 /** 1648 * Runs a snippet of code and encapsulates any throwable inside a {@link RuntimeException}. 1649 * 1650 * @param snippet The snippet of code to run. 1651 */ 1652 public static void safe(Snippet snippet) { 1653 try { 1654 snippet.run(); 1655 } catch (RuntimeException t) { 1656 throw t; 1657 } catch (Throwable t) { 1658 throw ThrowableUtils.toRex(t); 1659 } 1660 } 1661 1662 /** 1663 * Runs a snippet of code and silently ignores any exceptions. 1664 * 1665 * <p> 1666 * This method is useful for operations that may fail but where you want to handle the failure 1667 * gracefully by ignoring it. This is commonly used for "quietly" closing resources where 1668 * exceptions during close operations are not critical. 1669 * 1670 * <h5 class='section'>Example:</h5> 1671 * <p class='bjava'> 1672 * <jc>// Quietly close a stream, ignoring any exceptions</jc> 1673 * Utils.<jsm>quiet</jsm>(() -> stream.close()); 1674 * </p> 1675 * 1676 * <p> 1677 * This is different from {@link #safe(Snippet)} which wraps exceptions in a {@link RuntimeException}. 1678 * 1679 * @param snippet The snippet of code to run. 1680 * @see #safe(Snippet) 1681 * @see #safeOpt(ThrowingSupplier) 1682 */ 1683 public static void quiet(Snippet snippet) { 1684 try { 1685 snippet.run(); 1686 } catch (@SuppressWarnings("unused") Throwable t) { /* Ignore */ } 1687 } 1688 1689 /** 1690 * Runs a snippet of code with a custom exception mapper. 1691 * 1692 * <p> 1693 * This method allows you to define a function that converts any thrown throwable into a runtime exception. 1694 * This is useful when you need to wrap exceptions in a specific runtime exception type. 1695 * 1696 * <h5 class='section'>Example:</h5> 1697 * <p class='bjava'> 1698 * <jc>// Wrap code execution with custom exception handling</jc> 1699 * Utils.<jsm>safe</jsm>(() -> { 1700 * <jc>// some code that may throw</jc> 1701 * }, <jv>e</jv> -> <jk>new</jk> CustomRuntimeException(<jv>e</jv>)); 1702 * </p> 1703 * 1704 * @param snippet The snippet of code to run. 1705 * @param exceptionMapper A function that converts the thrown throwable into a runtime exception. 1706 * @throws RuntimeException The exception returned by the exception mapper if the snippet throws a throwable. 1707 */ 1708 public static void safe(Snippet snippet, Function<Throwable, RuntimeException> exceptionMapper) { 1709 try { 1710 snippet.run(); 1711 } catch (RuntimeException t) { 1712 throw t; 1713 } catch (Throwable t) { 1714 throw exceptionMapper.apply(t); 1715 } 1716 } 1717 1718 /** 1719 * Used to wrap code that returns a value but throws an exception. 1720 * Useful in cases where you're trying to execute code in a fluent method call 1721 * or are trying to eliminate untestable catch blocks in code. 1722 * 1723 * @param <T> The return type. 1724 * @param s The supplier that may throw an exception. 1725 * @return The result of the supplier execution. 1726 */ 1727 public static <T> T safe(ThrowingSupplier<T> s) { 1728 try { 1729 return s.get(); 1730 } catch (RuntimeException e) { 1731 throw e; 1732 } catch (Exception e) { 1733 throw rex(e); 1734 } 1735 } 1736 1737 /** 1738 * Used to wrap code that returns a value but throws an exception, with a custom exception mapper. 1739 * 1740 * <p> 1741 * This method allows you to define a function that converts any thrown exception into a runtime exception. 1742 * This is useful when you need to wrap exceptions in a specific runtime exception type (e.g., {@link org.apache.juneau.commons.reflect.ExecutableException}). 1743 * 1744 * <h5 class='section'>Example:</h5> 1745 * <p class='bjava'> 1746 * <jc>// Wrap a constructor invocation with custom exception handling</jc> 1747 * <jk>return</jk> Utils.<jsm>safe</jsm>(() -> { 1748 * <jk>try</jk> { 1749 * <jk>return</jk> (<jk>T</jk>)inner.newInstance(args); 1750 * } <jk>catch</jk> (InvocationTargetException <jv>e</jv>) { 1751 * <jk>throw new</jk> ExecutableException(<jv>e</jv>.getTargetException()); 1752 * } 1753 * }, <jv>e</jv> -> <jk>new</jk> ExecutableException(<jv>e</jv>)); 1754 * </p> 1755 * 1756 * @param <T> The return type. 1757 * @param s The supplier that may throw an exception. 1758 * @param exceptionMapper A function that converts the thrown exception into a runtime exception. 1759 * @return The result of the supplier execution. 1760 * @throws RuntimeException The exception returned by the exception mapper if the supplier throws an exception. 1761 */ 1762 public static <T> T safe(ThrowingSupplier<T> s, Function<Exception, RuntimeException> exceptionMapper) { 1763 try { 1764 return s.get(); 1765 } catch (RuntimeException e) { 1766 throw e; 1767 } catch (Exception e) { 1768 throw exceptionMapper.apply(e); 1769 } 1770 } 1771 1772 /** 1773 * Executes a supplier that may throw an exception and returns the result or a fallback value. 1774 * 1775 * <p> 1776 * If the supplier executes successfully, returns the result. 1777 * If the supplier throws any exception, applies the exception function to get a fallback value. 1778 * 1779 * <p> 1780 * This is useful for operations that may fail but you want to handle the failure 1781 * gracefully by returning a fallback value instead of throwing an exception. 1782 * 1783 * <h5 class='section'>Example:</h5> 1784 * <p class='bjava'> 1785 * <jc>// Get a value with a fallback if an exception occurs</jc> 1786 * <jk>String</jk> <jv>value</jv> = <jsm>safeCatch</jsm>(() -> <jv>riskyOperation</jv>(), <jv>e</jv> -> <js>"default"</js>); 1787 * </p> 1788 * 1789 * @param <T> The return type. 1790 * @param s The supplier that may throw an exception. 1791 * @param exceptionFunction A function that converts the thrown exception into a fallback value. 1792 * @return The result of the supplier execution, or the fallback value if an exception was thrown. 1793 * @see #safe(ThrowingSupplier) 1794 * @see #safeOptCatch(ThrowingSupplier, Function) 1795 */ 1796 public static <T> T safeCatch(ThrowingSupplier<T> s, Function<Throwable,T> exceptionFunction) { 1797 try { 1798 return s.get(); 1799 } catch (Throwable e) { 1800 return exceptionFunction.apply(e); 1801 } 1802 } 1803 1804 /** 1805 * Executes a supplier that may throw an exception and returns an Optional. 1806 * 1807 * <p> 1808 * If the supplier executes successfully, returns {@link Optional#of(Object)} with the result. 1809 * If the supplier throws any exception, returns {@link Optional#empty()}. 1810 * 1811 * <p> 1812 * This is useful for operations that may fail but you want to handle the failure 1813 * gracefully by returning an empty Optional instead of throwing an exception. 1814 * 1815 * <h5 class='section'>Example:</h5> 1816 * <p class='bjava'> 1817 * <jc>// Check if AccessibleObject.isAccessible() method exists (Java 9+)</jc> 1818 * <jk>boolean</jk> <jv>isAccessible</jv> = <jsm>safeOpt</jsm>(() -> 1819 * (<jk>boolean</jk>)AccessibleObject.<jk>class</jk>.getMethod(<js>"isAccessible"</js>).invoke(<jv>obj</jv>) 1820 * ).orElse(<jk>false</jk>); 1821 * </p> 1822 * 1823 * @param <T> The return type. 1824 * @param s The supplier that may throw an exception. 1825 * @return An Optional containing the result if successful, or empty if an exception was thrown. 1826 * @see #safe(ThrowingSupplier) 1827 * @see #opt(Object) 1828 */ 1829 public static <T> Optional<T> safeOpt(ThrowingSupplier<T> s) { 1830 try { 1831 return Optional.of(s.get()); 1832 } catch (@SuppressWarnings("unused") Exception e) { 1833 return Optional.empty(); 1834 } 1835 } 1836 1837 /** 1838 * Executes a supplier that may throw an exception and returns an Optional with the result or a fallback value. 1839 * 1840 * <p> 1841 * If the supplier executes successfully, returns {@link Optional#of(Object)} with the result. 1842 * If the supplier throws any exception, applies the exception function to get a fallback value and returns it wrapped in an Optional. 1843 * 1844 * <p> 1845 * This is useful for operations that may fail but you want to handle the failure 1846 * gracefully by returning a fallback value wrapped in an Optional instead of throwing an exception. 1847 * 1848 * <h5 class='section'>Example:</h5> 1849 * <p class='bjava'> 1850 * <jc>// Get a value with a fallback if an exception occurs</jc> 1851 * <jk>Optional</jk><<jk>String</jk>> <jv>value</jv> = <jsm>safeOptCatch</jsm>(() -> <jv>riskyOperation</jv>(), <jv>e</jv> -> <js>"default"</js>); 1852 * </p> 1853 * 1854 * @param <T> The return type. 1855 * @param s The supplier that may throw an exception. 1856 * @param exceptionFunction A function that converts the thrown exception into a fallback value. 1857 * @return An Optional containing the result if successful, or the fallback value wrapped in an Optional if an exception was thrown. 1858 * @see #safeOpt(ThrowingSupplier) 1859 * @see #safeCatch(ThrowingSupplier, Function) 1860 * @see #opt(Object) 1861 */ 1862 public static <T> Optional<T> safeOptCatch(ThrowingSupplier<T> s, Function<Throwable,T> exceptionFunction) { 1863 try { 1864 return opt(s.get()); 1865 } catch (Throwable e) { 1866 return opt(exceptionFunction.apply(e)); 1867 } 1868 } 1869 1870 /** 1871 * Executes a supplier that may throw an exception and returns the result or <c>null</c>. 1872 * 1873 * <p> 1874 * If the supplier executes successfully, returns the result. 1875 * If the supplier throws any exception, returns <c>null</c>. 1876 * 1877 * <p> 1878 * This is useful for operations that may fail but you want to handle the failure 1879 * gracefully by returning <c>null</c> instead of throwing an exception. This is particularly 1880 * useful in fluent method chains where you want to filter out failed conversions. 1881 * 1882 * <p> 1883 * This method is similar to {@link #safeOpt(ThrowingSupplier)} but returns <c>null</c> instead 1884 * of <c>Optional.empty()</c> when an exception occurs. Use this method when you prefer <c>null</c> 1885 * over <c>Optional</c> for error handling. 1886 * 1887 * <h5 class='section'>Example:</h5> 1888 * <p class='bjava'> 1889 * <jc>// Parse an integer, returning null if parsing fails</jc> 1890 * Integer <jv>value</jv> = <jsm>safeOrNull</jsm>(() -> Integer.valueOf(<js>"123"</js>)); <jc>// 123</jc> 1891 * Integer <jv>invalid</jv> = <jsm>safeOrNull</jsm>(() -> Integer.valueOf(<js>"abc"</js>)); <jc>// null</jc> 1892 * 1893 * <jc>// Use in a fluent chain to filter out failed conversions</jc> 1894 * Optional<Integer> <jv>parsed</jv> = get(<js>"my.property"</js>) 1895 * .map(<jv>v</jv> -> <jsm>safeOrNull</jsm>(() -> Integer.valueOf(<jv>v</jv>))) 1896 * .filter(Objects::nonNull); 1897 * </p> 1898 * 1899 * @param <T> The return type. 1900 * @param s The supplier that may throw an exception. 1901 * @return The result of the supplier if successful, or <c>null</c> if an exception was thrown. 1902 * @see #safeOpt(ThrowingSupplier) 1903 * @see #safe(ThrowingSupplier) 1904 */ 1905 public static <T> T safeOrNull(ThrowingSupplier<T> s) { 1906 return safeOpt(s).orElse(null); 1907 } 1908 1909 /** 1910 * Allows you to wrap a supplier that throws an exception so that it can be used in a fluent interface. 1911 * 1912 * @param <T> The supplier type. 1913 * @param supplier The supplier throwing an exception. 1914 * @return The supplied result. 1915 * @throws RuntimeException if supplier threw an exception. 1916 */ 1917 public static <T> T safeSupplier(ThrowableUtils.SupplierWithThrowable<T> supplier) { 1918 try { 1919 return supplier.get(); 1920 } catch (RuntimeException t) { 1921 throw t; 1922 } catch (Throwable t) { 1923 throw toRex(t); 1924 } 1925 } 1926 1927 /** 1928 * Allows you to wrap a supplier that throws an exception with a custom exception mapper. 1929 * 1930 * <p> 1931 * This method allows you to define a function that converts any thrown throwable into a runtime exception. 1932 * This is useful when you need to wrap exceptions in a specific runtime exception type. 1933 * 1934 * <h5 class='section'>Example:</h5> 1935 * <p class='bjava'> 1936 * <jc>// Wrap a supplier with custom exception handling</jc> 1937 * <jk>return</jk> Utils.<jsm>safeSupplier</jsm>(() -> { 1938 * <jc>// some code that may throw</jc> 1939 * <jk>return</jk> <jv>result</jv>; 1940 * }, <jv>e</jv> -> <jk>new</jk> CustomRuntimeException(<jv>e</jv>)); 1941 * </p> 1942 * 1943 * @param <T> The supplier type. 1944 * @param supplier The supplier throwing an exception. 1945 * @param exceptionMapper A function that converts the thrown throwable into a runtime exception. 1946 * @return The supplied result. 1947 * @throws RuntimeException The exception returned by the exception mapper if the supplier threw a throwable. 1948 */ 1949 public static <T> T safeSupplier(ThrowableUtils.SupplierWithThrowable<T> supplier, Function<Throwable, RuntimeException> exceptionMapper) { 1950 try { 1951 return supplier.get(); 1952 } catch (RuntimeException t) { 1953 throw t; 1954 } catch (Throwable t) { 1955 throw exceptionMapper.apply(t); 1956 } 1957 } 1958 1959 /** 1960 * Helper method for creating StringBuilder objects. 1961 * 1962 * @param value The string value to wrap in a StringBuilder. 1963 * @return A new StringBuilder containing the specified value. 1964 */ 1965 public static StringBuilder sb(String value) { 1966 return new StringBuilder(value); 1967 } 1968 1969 /** 1970 * Shortcut for calling {@link StringUtils#stringSupplier(Supplier)}. 1971 * 1972 * @param s The supplier. 1973 * @return A string supplier that calls {@link #r(Object)} on the supplied value. 1974 */ 1975 public static Supplier<String> ss(Supplier<?> s) { 1976 return stringSupplier(s); 1977 } 1978 1979 /** 1980 * Convenience method for calling {@link StringUtils#upperCase(String)}. 1981 * 1982 * <p> 1983 * Converts the string to uppercase if not null. 1984 * 1985 * @param value The string to convert. 1986 * @return The uppercase string, or <jk>null</jk> if the input was <jk>null</jk>. 1987 */ 1988 public static String uc(String value) { 1989 return StringUtils.upperCase(value); 1990 } 1991 1992 /** 1993 * Shortcut for calling {@link StringUtils#isBlank(CharSequence)}. 1994 * 1995 * <p> 1996 * Returns <jk>true</jk> if the string is blank (null, empty, or whitespace only). 1997 * 1998 * <h5 class='section'>Example:</h5> 1999 * <p class='bjava'> 2000 * b(<jk>null</jk>); <jc>// true</jc> 2001 * b(<js>""</js>); <jc>// true</jc> 2002 * b(<js>" "</js>); <jc>// true</jc> 2003 * b(<js>"hello"</js>); <jc>// false</jc> 2004 * </p> 2005 * 2006 * @param str The string to check. 2007 * @return <jk>true</jk> if the string is blank. 2008 * @see StringUtils#isBlank(CharSequence) 2009 * @see #nb(String) 2010 */ 2011 public static boolean b(String str) { 2012 return StringUtils.isBlank(str); 2013 } 2014 2015 /** 2016 * Shortcut for calling {@link StringUtils#isNotBlank(CharSequence)}. 2017 * 2018 * <p> 2019 * Returns <jk>true</jk> if the string is not blank (not null, not empty, and contains non-whitespace). 2020 * 2021 * <h5 class='section'>Example:</h5> 2022 * <p class='bjava'> 2023 * nb(<js>"hello"</js>); <jc>// true</jc> 2024 * nb(<jk>null</jk>); <jc>// false</jc> 2025 * nb(<js>""</js>); <jc>// false</jc> 2026 * nb(<js>" "</js>); <jc>// false</jc> 2027 * </p> 2028 * 2029 * @param str The string to check. 2030 * @return <jk>true</jk> if the string is not blank. 2031 * @see StringUtils#isNotBlank(CharSequence) 2032 * @see #b(String) 2033 */ 2034 public static boolean nb(String str) { 2035 return StringUtils.isNotBlank(str); 2036 } 2037 2038 /** 2039 * Shortcut for calling {@link StringUtils#trim(String)}. 2040 * 2041 * <p> 2042 * Trims whitespace from both ends of the string. 2043 * 2044 * <h5 class='section'>Example:</h5> 2045 * <p class='bjava'> 2046 * tr(<js>" hello "</js>); <jc>// "hello"</jc> 2047 * tr(<js>"hello"</js>); <jc>// "hello"</jc> 2048 * tr(<jk>null</jk>); <jc>// null</jc> 2049 * </p> 2050 * 2051 * @param str The string to trim. 2052 * @return The trimmed string, or <jk>null</jk> if the input was <jk>null</jk>. 2053 * @see StringUtils#trim(String) 2054 */ 2055 public static String tr(String str) { 2056 return StringUtils.trim(str); 2057 } 2058 2059 /** 2060 * Tests if the string starts with the specified prefix. 2061 * 2062 * <p> 2063 * Null-safe operation. Returns <jk>false</jk> if either string is <jk>null</jk>. 2064 * 2065 * <h5 class='section'>Example:</h5> 2066 * <p class='bjava'> 2067 * sw(<js>"hello"</js>, <js>"he"</js>); <jc>// true</jc> 2068 * sw(<js>"hello"</js>, <js>"lo"</js>); <jc>// false</jc> 2069 * sw(<jk>null</jk>, <js>"he"</js>); <jc>// false</jc> 2070 * </p> 2071 * 2072 * @param str The string to test. 2073 * @param prefix The prefix to test for. 2074 * @return <jk>true</jk> if the string starts with the prefix. 2075 */ 2076 public static boolean sw(String str, String prefix) { 2077 return and(nn(str), nn(prefix)) && str.startsWith(prefix); 2078 } 2079 2080 /** 2081 * Tests if the string ends with the specified suffix. 2082 * 2083 * <p> 2084 * Null-safe operation. Returns <jk>false</jk> if either string is <jk>null</jk>. 2085 * 2086 * <h5 class='section'>Example:</h5> 2087 * <p class='bjava'> 2088 * ew(<js>"hello"</js>, <js>"lo"</js>); <jc>// true</jc> 2089 * ew(<js>"hello"</js>, <js>"he"</js>); <jc>// false</jc> 2090 * ew(<jk>null</jk>, <js>"lo"</js>); <jc>// false</jc> 2091 * </p> 2092 * 2093 * @param str The string to test. 2094 * @param suffix The suffix to test for. 2095 * @return <jk>true</jk> if the string ends with the suffix. 2096 */ 2097 public static boolean ew(String str, String suffix) { 2098 return and(nn(str), nn(suffix)) && str.endsWith(suffix); 2099 } 2100 2101 /** 2102 * Tests if the string contains the specified substring. 2103 * 2104 * <p> 2105 * Null-safe operation. Returns <jk>false</jk> if either string is <jk>null</jk>. 2106 * 2107 * <h5 class='section'>Example:</h5> 2108 * <p class='bjava'> 2109 * co(<js>"hello"</js>, <js>"ell"</js>); <jc>// true</jc> 2110 * co(<js>"hello"</js>, <js>"xyz"</js>); <jc>// false</jc> 2111 * co(<jk>null</jk>, <js>"ell"</js>); <jc>// false</jc> 2112 * </p> 2113 * 2114 * @param str The string to test. 2115 * @param substring The substring to search for. 2116 * @return <jk>true</jk> if the string contains the substring. 2117 */ 2118 public static boolean co(String str, String substring) { 2119 return and(nn(str), nn(substring)) && str.contains(substring); 2120 } 2121 2122 /** 2123 * If the specified object is a {@link Supplier} or {@link Value}, returns the inner value, otherwise the same value. 2124 * 2125 * @param o The object to unwrap. 2126 * @return The unwrapped object. 2127 */ 2128 public static Object unwrap(Object o) { 2129 if (o instanceof Supplier<?> o2) 2130 o = unwrap(o2.get()); 2131 if (o instanceof Value<?> o2) 2132 o = unwrap(o2.get()); 2133 if (o instanceof Optional<?> o2) 2134 o = unwrap(o2.orElse(null)); 2135 return o; 2136 } 2137 2138 /** Constructor - This class is meant to be subclasses. */ 2139 protected Utils() {} 2140 2141 /** 2142 * Returns the specified string, or <jk>null</jk> if that string is <jk>null</jk> or empty. 2143 * 2144 * @param value The string value to check. 2145 * @return The string value, or <jk>null</jk> if the string is <jk>null</jk> or empty. 2146 */ 2147 public static String nullIfEmpty(String value) { 2148 return StringUtils.isEmpty(value) ? null : value; 2149 } 2150 2151 /** 2152 * Returns <jk>null</jk> if the specified map is <jk>null</jk> or empty, otherwise returns the map. 2153 * 2154 * <p> 2155 * This is a convenience method for preserving backward compatibility when maps are initialized immediately 2156 * but getters should return <jk>null</jk> if the map is empty. 2157 * 2158 * @param <K> The key type. 2159 * @param <V> The value type. 2160 * @param val The map to check. 2161 * @return <jk>null</jk> if the map is <jk>null</jk> or empty, otherwise the map itself. 2162 */ 2163 public static <K,V> Map<K,V> nullIfEmpty(Map<K,V> val) { 2164 return e(val) ? null : val; 2165 } 2166 2167 /** 2168 * Returns <jk>null</jk> if the specified list is <jk>null</jk> or empty, otherwise returns the list. 2169 * 2170 * <p> 2171 * This is a convenience method for preserving backward compatibility when lists are initialized immediately 2172 * but getters should return <jk>null</jk> if the list is empty. 2173 * 2174 * @param <E> The element type. 2175 * @param val The list to check. 2176 * @return <jk>null</jk> if the list is <jk>null</jk> or empty, otherwise the list itself. 2177 */ 2178 public static <E> List<E> nullIfEmpty(List<E> val) { 2179 return e(val) ? null : val; 2180 } 2181 2182 /** 2183 * Returns <jk>null</jk> if the specified set is <jk>null</jk> or empty, otherwise returns the set. 2184 * 2185 * <p> 2186 * This is a convenience method for preserving backward compatibility when sets are initialized immediately 2187 * but getters should return <jk>null</jk> if the set is empty. 2188 * 2189 * @param <E> The element type. 2190 * @param val The set to check. 2191 * @return <jk>null</jk> if the set is <jk>null</jk> or empty, otherwise the set itself. 2192 */ 2193 public static <E> Set<E> nullIfEmpty(Set<E> val) { 2194 return e(val) ? null : val; 2195 } 2196 2197}