All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.lirmm.boreal.util.enumerations.EnumUtils Maven / Gradle / Ivy

There is a newer version: 1.6.3
Show newest version
package fr.lirmm.boreal.util.enumerations;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility class providing various facilities for working with enumerations.
 */
public class EnumUtils {

	/** Logger instance for logging errors and information. */
	static final Logger LOG = LoggerFactory.getLogger(EnumUtils.class);

	/**
	 * Searches for an enum constant of the specified type that matches the given
	 * value. The search is case-insensitive. If a matching enum constant is found,
	 * it is returned. If no match is found, an {@code IllegalArgumentException} is
	 * thrown with a detailed error message. Additionally, the method performs
	 * checks to ensure that neither the enum class nor the value is null or empty.
	 *
	 * @param    The enum type whose constants are being searched.
	 * @param value The string representation of the enum constant to search for.
	 *              This comparison is case-insensitive.
	 * @param clazz The {@code Class} object of the enum type in which to search.
	 * @return The enum constant that matches the given value.
	 * @throws IllegalArgumentException If the enum class or value is null or empty,
	 *                                  or if no matching enum constant is found.
	 */
	public static > E findEnumFromString(String value, Class clazz)
			throws IllegalArgumentException {
		// Check if the enum class or value is null or empty
		if (clazz == null) {
			throw new IllegalArgumentException("Enum class must not be null");
		}
		if (value == null || value.trim().isEmpty()) {
			throw new IllegalArgumentException("Value must not be null or empty");
		}

		// Search for the enum constant that matches the value (case-insensitive)
		for (E constant : clazz.getEnumConstants()) {
			if (constant.toString().equalsIgnoreCase(value)) {
				return constant;
			}
		}

		// If no match is found, log the error and throw an exception
		String template = """
				Value %s not found among options for parameter %s.
				Supported options only include %s.
				""";
		String message = String.format(template, value, clazz.getCanonicalName(),
				String.join(", ", getAllConstantsAsString(clazz)));

		LOG.error(message);
		throw new IllegalArgumentException(message);
	}

	/**
	 * Returns an array of strings containing all the constants of the specified
	 * enum type. This can be useful for logging or displaying the available options
	 * for an enum.
	 *
	 * @param        The enum type.
	 * @param enumClass The {@code Class} object of the enum type whose constants
	 *                  are to be listed.
	 * @return An array of strings representing the names of the constants of the
	 *         enum type.
	 */
	public static > String[] getAllConstantsAsString(Class enumClass) {
		return Arrays.stream(enumClass.getEnumConstants()).map(Enum::toString).toArray(String[]::new);
	}
	
	
	
	/**
	 * Recursively searches through an enum class and its nested enums to find a
	 * nested enum class that matches the given name.
	 * 
	 * @param clazz The enum class to start the search with.
	 * @param name  The name of the nested enum class to find.
	 * @return The matching nested enum class if found, otherwise null.
	 */
	@SuppressWarnings("unchecked")
	public static Class> findNestedEnumClassByName(Class> clazz, String name) {
	    if (clazz == null) {
	        throw new IllegalArgumentException("Class must not be null");
	    }
	    if (name == null || name.trim().isEmpty()) {
	        throw new IllegalArgumentException("Name must not be null or empty");
	    }

	    // Check if the class itself matches the name
	    if (clazz.getSimpleName().equalsIgnoreCase(name)) {
	        return clazz;
	    }

	    // Recursively search in nested classes
	    for (Class nestedClass : clazz.getDeclaredClasses()) {
	        if (nestedClass.isEnum()) {
	            Class> found = findNestedEnumClassByName((Class>) nestedClass, name);
	            if (found != null) {
	                return found;
	            }
	        }
	    }

	    return null;
	}

	
	
	
	
	/**
	 * Recursively searches for an enum class that matches the given value
	 * by exploring the nested enum classes from the given root enum class.
	 * The search is case-insensitive. If a matching enum class is found,
	 * it is returned. Else null is returned. An {@code IllegalArgumentException}
	 * is thrown if the given class is null or is not an enum class or if the value
	 * is null or empty. 
	 * 
	 * @param enumClass The {@code Class} object of the enum type in which to search.
	 * @param value The string representation of the enum class to search for.
	 *              This comparison is case-insensitive.
	 * @return The enum class if found, otherwise null.
	 * @throws IllegalArgumentException If the class is null or not an enum class
	 * 									or the value is null or empty.	
	 */
	public static Class> findEnumClassInNestedEnumeration(String value, Class> enumClass) {
		if (enumClass == null) {
			throw new IllegalArgumentException("Enum class must not be null");
		}
		if (value == null || value.trim().isEmpty()) {
			throw new IllegalArgumentException("Name of searched enum must not be null or empty");
		}
		if (enumClass.isEnum() && enumClass.getSimpleName().equalsIgnoreCase(value)) {
			return enumClass;
		}
		// Recursively search in nested classes
		for (Class nestedClass : enumClass.getDeclaredClasses()) {
			@SuppressWarnings("unchecked")
			Class> found = findEnumClassInNestedEnumeration(value,(Class>)nestedClass);
			if (found != null) {
				return found;
			}
		}
		return null;
	}


	/**
	 * Searches for an enum constant of the specified type that matches the given
	 * value. The search is case-insensitive. If a matching enum constant is found,
	 * it is returned. If no match is found, an {@code IllegalArgumentException} is
	 * thrown with a detailed error message. Additionally, the method performs
	 * checks to ensure that neither the enum class nor the value is null or empty.
	 * 
	 * @param enumClass The {@code Class} object of the enum type in which to search..
	 * @param value The string representation of the enum constant to search for.
	 *              This comparison is case-insensitive.
	 * @return The enum constant that matches the given value if found, otherwise null.
	 * @throws IllegalArgumentException If the class is null or not an enum class
	 * 									or the value is null or empty.
	 */
	public static Enum findConstantInEnumeration(String value, Class> enumClass) {
		if (enumClass == null) {
			throw new IllegalArgumentException("Class must not be null");
		}
		if (value == null || value.trim().isEmpty()) {
			throw new IllegalArgumentException("Value must not be null or empty");
		}
		if (!enumClass.isEnum()){
			throw new IllegalArgumentException("Class must be an Enum");
		}
		for (Object enumConstant : enumClass.getEnumConstants()) {
			Enum enumConst = (Enum) enumConstant;
			if (enumConst.name().equalsIgnoreCase(value)) {
				return enumConst;
			}
		}
		return null;
	}	



	/**
	 * Recursively searches through an enumeration and its nested enums to find a
	 * constant matching the given name.
	 * 
	 * @param clazz The class to start the search with.
	 * @param name  The name of the enum constant to find.
	 * @return The enum constant if found, otherwise null.
	 */
	public static Enum findConstantInNestedEnumeration(Class clazz, String name) {

		if (clazz == null) {
			throw new IllegalArgumentException("Enum class must not be null");
		}
		if (name == null || name.trim().isEmpty()) {
			throw new IllegalArgumentException("Value must not be null or empty");
		}

		if (clazz.isEnum()) {
			for (Object enumConstant : clazz.getEnumConstants()) {
				Enum enumConst = (Enum) enumConstant;
				if (enumConst.name().equalsIgnoreCase(name)) {
					return enumConst;
				}
			}
		}

		// Recursively search in nested classes
		for (Class nestedClass : clazz.getDeclaredClasses()) {
			Enum found = findConstantInNestedEnumeration(nestedClass, name);
			if (found != null) {
				return found;
			}
		}

		return null;
	}

	/**
	 * 
	 * @param 
	 * @param value
	 * @param clazz
	 * @return null if the string is null or empty and the corresponding enumeration
	 *         otherwise ; an error IllegalArgumentException is raised if the string
	 *         does not correspond to any enumeration
	 */
	public static > E getEnumerationFromString(String value, Class clazz) {
		return switch (value) {
		case null -> null;
		case String s when s.equals("") -> null;
		default -> EnumUtils.findEnumFromString(value, clazz);
		};

	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy