001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.internal; 014 015import java.lang.reflect.*; 016import java.util.*; 017import java.util.function.*; 018 019import org.apache.juneau.utils.*; 020 021/** 022 * Various generic object utility methods. 023 */ 024public class ObjectUtils { 025 026 /** 027 * Returns the enum names for the specified enum class. 028 * 029 * @param c The enum class. 030 * @return A modifiable list of all names for that class. 031 */ 032 @SuppressWarnings("unchecked") 033 public static Enum<?>[] getEnumConstants(Class<?> c) { 034 return ((Class<Enum<?>>)c).getEnumConstants(); 035 } 036 037 /** 038 * If the specified object is an instance of the specified class, casts it to that type. 039 * 040 * @param o The object to cast. 041 * @param c The class to cast to. 042 * @return The cast object, or <jk>null</jk> if the object wasn't an instance of the specified class. 043 */ 044 @SuppressWarnings("unchecked") 045 public static <T> T castOrNull(Object o, Class<T> c) { 046 if (c.isInstance(o)) 047 return (T)o; 048 return null; 049 } 050 051 /** 052 * Returns the first non-zero value in the list of ints. 053 * 054 * @param ints The ints to check. 055 * @return The first non-zero value, or <c>0</c> if they were all zero. 056 */ 057 public static int firstNonZero(int...ints) { 058 for (int i : ints) 059 if (i != 0) 060 return i; 061 return 0; 062 } 063 064 /** 065 * Returns the first non-empty value in the list of objects. 066 * 067 * @param o The objects to check. 068 * @return The first object whose call to {@link ObjectUtils#isEmpty(Object)} returns <jk>false</jk>, otherwise <jk>null</jk>. 069 */ 070 @SafeVarargs 071 public static <T> T firstNonEmpty(T...o) { 072 for (T oo : o) 073 if (! ObjectUtils.isEmpty(oo)) 074 return oo; 075 return null; 076 } 077 078 /** 079 * Compares two objects for equality. 080 * 081 * <p> 082 * Nulls are always considered less-than unless both are null. 083 * 084 * @param o1 Object 1. 085 * @param o2 Object 2. 086 * @return 087 * <c>-1</c>, <c>0</c>, or <c>1</c> if <c>o1</c> is less-than, equal, or greater-than <c>o2</c>. 088 * <br><c>0</c> if objects are not of the same type or do not implement the {@link Comparable} interface. 089 */ 090 @SuppressWarnings({ "rawtypes", "unchecked" }) 091 public static int compare(Object o1, Object o2) { 092 if (o1 == null) { 093 if (o2 == null) 094 return 0; 095 return -1; 096 } else if (o2 == null) { 097 return 1; 098 } 099 100 if (o1.getClass() == o2.getClass() && o1 instanceof Comparable) 101 return ((Comparable)o1).compareTo(o2); 102 103 return 0; 104 } 105 106 /** 107 * Compare two integers numerically. 108 * 109 * @param i1 Integer #1 110 * @param i2 Integer #2 111 * @return 112 * The value <c>0</c> if Integer #1 is equal to Integer #2; a value less than <c>0</c> if 113 * Integer #1 numerically less than Integer #2; and a value greater than <c>0</c> if Integer #1 is 114 * numerically greater than Integer #2 (signed comparison). 115 */ 116 public static final int compare(int i1, int i2) { 117 return (i1<i2 ? -1 : (i1==i2 ? 0 : 1)); 118 } 119 120 /** 121 * Tests two objects for equality, gracefully handling nulls. 122 * 123 * @param <T> Object 1 type. 124 * @param <U> Object 2 type. 125 * @param o1 Object 1. 126 * @param o2 Object 2. 127 * @param test The test to use for equality. 128 * @return <jk>true</jk> if both objects are equal based on the test. 129 */ 130 public static <T,U> boolean eq(T o1, U o2, BiPredicate<T,U> test) { 131 if (o1 == null) 132 return o2 == null; 133 if (o2 == null) 134 return false; 135 if (o1 == o2) 136 return true; 137 return test.test(o1, o2); 138 } 139 140 /** 141 * Tests two objects for equality, gracefully handling nulls. 142 * 143 * @param o1 Object 1. 144 * @param o2 Object 2. 145 * @return <jk>true</jk> if both objects are equal based on the {@link Object#equals(Object)} method. 146 */ 147 public static boolean eq(Object o1, Object o2) { 148 return Objects.equals(o1, o2); 149 } 150 151 /** 152 * Tests two objects for inequality, gracefully handling nulls. 153 * 154 * @param <T> Object 1 type. 155 * @param <U> Object 2 type. 156 * @param o1 Object 1. 157 * @param o2 Object 2. 158 * @param test The test to use for equality. 159 * @return <jk>false</jk> if both objects are equal based on the test. 160 */ 161 public static <T,U> boolean ne(T o1, U o2, BiPredicate<T,U> test) { 162 if (o1 == null) 163 return o2 != null; 164 if (o2 == null) 165 return true; 166 if (o1 == o2) 167 return false; 168 return ! test.test(o1, o2); 169 } 170 171 /** 172 * Tests two objects for equality, gracefully handling nulls. 173 * 174 * @param o1 Object 1. 175 * @param o2 Object 2. 176 * @return <jk>false</jk> if both objects are equal based on the {@link Object#equals(Object)} method. 177 */ 178 public static boolean ne(Object o1, Object o2) { 179 return ! Objects.equals(o1, o2); 180 } 181 182 /** 183 * If the specified object is a {@link Supplier} or {@link Mutable}, returns the inner value, otherwise the same value. 184 * 185 * @param o The object to unwrap. 186 * @return The unwrapped object. 187 */ 188 public static Object unwrap(Object o) { 189 while (o instanceof Supplier) 190 o = ((Supplier<?>)o).get(); 191 while (o instanceof Mutable) 192 o = ((Mutable<?>)o).get(); 193 return o; 194 } 195 196 /** 197 * Returns <jk>true</jk> if the specified object is empty. 198 * 199 * <p> 200 * Return <jk>true</jk> if the value is any of the following: 201 * <ul> 202 * <li><jk>null</jk> 203 * <li>An empty Collection 204 * <li>An empty Map 205 * <li>An empty array 206 * <li>An empty CharSequence 207 * <li>An empty String when serialized to a string using {@link Object#toString()}. 208 * </ul> 209 * 210 * @param o The object to test. 211 * @return <jk>true</jk> if the specified object is empty. 212 */ 213 @SuppressWarnings("rawtypes") 214 public static boolean isEmpty(Object o) { 215 if (o == null) 216 return true; 217 if (o instanceof Collection) 218 return ((Collection)o).isEmpty(); 219 if (o instanceof Map) 220 return ((Map)o).isEmpty(); 221 if (o.getClass().isArray()) 222 return (Array.getLength(o) == 0); 223 return o.toString().isEmpty(); 224 } 225 226 /** 227 * Returns <jk>true</jk> if the specified object is not empty. 228 * 229 * <p> 230 * Return <jk>false</jk> if the value is any of the following: 231 * <ul> 232 * <li><jk>null</jk> 233 * <li>An empty Collection 234 * <li>An empty Map 235 * <li>An empty array 236 * <li>An empty CharSequence 237 * <li>An empty String when serialized to a string using {@link Object#toString()}. 238 * </ul> 239 * 240 * @param o The object to test. 241 * @return <jk>true</jk> if the specified object is empty. 242 */ 243 public static boolean isNotEmpty(Object o) { 244 return ! isEmpty(o); 245 } 246 247 /** 248 * Returns the first non-null value in the specified array 249 * 250 * @param t The values to check. 251 * @return The first non-null value, or <jk>null</jk> if the array is null or empty or contains only <jk>null</jk> values. 252 */ 253 @SafeVarargs 254 public static <T> T firstNonNull(T... t) { 255 if (t != null) 256 for (T tt : t) 257 if (tt != null) 258 return tt; 259 return null; 260 } 261}