org.apache.juneau.internal.ObjectUtils Maven / Gradle / Ivy
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
// * with the License. You may obtain a copy of the License at *
// * *
// * http://www.apache.org/licenses/LICENSE-2.0 *
// * *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
package org.apache.juneau.internal;
import java.lang.reflect.*;
import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.transform.*;
/**
* Utility class for efficiently converting objects between types.
*
*
* If the value isn't an instance of the specified type, then converts the value if possible.
*
*
* The following conversions are valid:
*
* Convert to type Valid input value types Notes
*
*
* A class that is the normal type of a registered {@link PojoSwap}.
*
*
* A value whose class matches the transformed type of that registered {@link PojoSwap}.
*
*
*
*
*
* A class that is the transformed type of a registered {@link PojoSwap}.
*
*
* A value whose class matches the normal type of that registered {@link PojoSwap}.
*
*
*
*
*
* {@code Number} (e.g. {@code Integer}, {@code Short}, {@code Float},...)
*
Number.TYPE
(e.g. Integer.TYPE
,
* Short.TYPE
, Float.TYPE
,...)
*
*
* {@code Number}, {@code String}, null
*
*
* For primitive {@code TYPES}, null returns the JVM default value for that type.
*
*
*
*
* {@code Map} (e.g. {@code Map}, {@code HashMap}, {@code TreeMap}, {@code ObjectMap})
*
*
* {@code Map}
*
*
* If {@code Map} is not constructible, a {@code ObjectMap} is created.
*
*
*
*
* Collection
(e.g. List
, LinkedList
, HashSet
, ObjectList
)
*
*
* Collection<Object>
*
Object[]
*
*
* If Collection
is not constructible, a ObjectList
is created.
*
*
*
*
* X[]
(array of any type X)
*
*
* List<X>
*
*
*
*
*
* X[][]
(multi-dimensional arrays)
*
*
* List<List<X>>
*
List<X[]>
*
List[]<X>
*
*
*
*
*
* Enum
*
*
* String
*
*
*
*
*
* Bean
*
*
* Map
*
*
*
*
*
* String
*
*
* Anything
*
*
* Arrays are converted to JSON arrays
*
*
*
*
* Anything with one of the following methods:
*
public static T fromString(String)
*
public static T valueOf(String)
*
public T(String)
*
*
* String
*
*
*
*
*
*
*/
public final class ObjectUtils {
// Session objects are usually not thread safe, but we're not using any feature
// of bean sessions that would cause thread safety issues.
private static final BeanSession session = BeanContext.DEFAULT.createSession();
/**
* Converts the specified object to the specified type.
*
* @param The class type to convert the value to.
* @param value The value to convert.
* @param type The class type to convert the value to.
* @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
* @return The converted value.
*/
public static T toType(Object value, Class type) {
return session.convertToType(value, type);
}
/**
* Converts the specified object to the specified type.
*
* @param The class type to convert the value to.
* @param value The value to convert.
* @param type The class type to convert the value to.
* @param args The type arguments.
* @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
* @return The converted value.
*/
public static T toType(Object value, Class type, Type...args) {
return session.convertToType(value, type, args);
}
/**
* Converts the specified object to the specified type.
*
* @param The class type to convert the value to.
* @param outer
* If class is a member class, this is the instance of the containing class.
* Should be null if not a member class.
* @param value The value to convert.
* @param type The class type to convert the value to.
* @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
* @return The converted value.
*/
public static T toMemberType(Object outer, Object value, Class type) {
return session.convertToMemberType(outer, value, type);
}
/**
* Returns true if the specified objects are equal.
*
*
* Gracefully handles null s.
*
* @param o1 Object #1
* @param o2 Object #2
* @return true if the objects are equal or both null .
*/
public static boolean equals(Object o1, Object o2) {
if (o1 == null && o2 == null)
return true;
if (o1 == null || o2 == null)
return false;
return o1.equals(o2);
}
/**
* Returns true if the specified object is empty.
*
*
* Return true if the value is any of the following:
*
* null
* - An empty Collection
*
- An empty Map
*
- An empty array
*
- An empty CharSequence
*
- An empty String when serialized to a string using {@link Object#toString()}.
*
*
* @param o The object to test.
* @return true if the specified object is empty.
*/
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Object o) {
if (o == null)
return true;
if (o instanceof Collection)
return ((Collection)o).isEmpty();
if (o instanceof Map)
return ((Map)o).isEmpty();
if (o.getClass().isArray())
return (Array.getLength(o) == 0);
return o.toString().isEmpty();
}
/**
* Returns the first non-null value in the specified array
*
* @param t
* @return The first non-null value, or null if the array is null or empty or contains only null values.
*/
@SafeVarargs
public static T firstNonNull(T... t) {
if (t != null)
for (T tt : t)
if (tt != null)
return tt;
return null;
}
/**
* Converts an object to a Boolean.
*
* @param o The object to convert.
* @return The converted object.
*/
public static Boolean toBoolean(Object o) {
return toType(o, Boolean.class);
}
/**
* Converts an object to an Integer.
*
* @param o The object to convert.
* @return The converted object.
*/
public static Integer toInteger(Object o) {
return toType(o, Integer.class);
}
/**
* Converts an object to a Number.
*
* @param o The object to convert.
* @return The converted object.
*/
public static Number toNumber(Object o) {
if (o == null)
return null;
if (o instanceof Number)
return (Number)o;
try {
return StringUtils.parseNumber(o.toString(), null);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* Returns the enum names for the specified enum class.
*
* @param c The enum class.
* @return A modifiable list of all names for that class.
*/
@SuppressWarnings("unchecked")
public static Enum>[] getEnumConstants(Class> c) {
return ((Class>)c).getEnumConstants();
}
/**
* If the specified object is an instance of the specified class, casts it to that type.
*
* @param o The object to cast.
* @param c The class to cast to.
* @return The cast object, or null if the object wasn't an instance of the specified class.
*/
@SuppressWarnings("unchecked")
public static T castOrNull(Object o, Class c) {
if (c.isInstance(o))
return (T)o;
return null;
}
/**
* Returns the first non-zero value in the list of ints.
*
* @param ints The ints to check.
* @return The first non-zero value, or 0
if they were all zero.
*/
public static int firstNonZero(int...ints) {
for (int i : ints)
if (i != 0)
return i;
return 0;
}
/**
* Returns the first non-empty value in the list of objects.
*
* @param o The objects to check.
* @return The first object whose call to {@link #isEmpty(Object)} returns false , otherwise null .
*/
@SafeVarargs
public static T firstNonEmpty(T...o) {
for (T oo : o)
if (! isEmpty(oo))
return oo;
return null;
}
}