Example usage for java.lang Enum valueOf

List of usage examples for java.lang Enum valueOf

Introduction

In this page you can find the example usage for java.lang Enum valueOf.

Prototype

public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 

Source Link

Document

Returns the enum constant of the specified enum type with the specified name.

Usage

From source file:org.sonar.api.server.ws.Request.java

@CheckForNull
public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) {
    String value = param(key);//  w ww. ja  v  a  2 s  . c  om
    if (value == null) {
        return null;
    }
    Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
    List<E> result = new ArrayList<>();
    for (String s : values) {
        result.add(Enum.valueOf(enumClass, s));
    }

    return result;
}

From source file:ch.algotrader.esper.EngineImpl.java

private void initVariables(final Configuration configuration, final ConfigParams configParams) {

    Map<String, ConfigurationVariable> variables = configuration.getVariables();
    for (Map.Entry<String, ConfigurationVariable> entry : variables.entrySet()) {
        String variableName = entry.getKey().replace("_", ".");
        String value = configParams.getString(variableName);
        if (value != null) {
            String type = entry.getValue().getType();
            try {
                Class clazz = Class.forName(type);
                Object typedObj;/*from w  w  w.  ja v  a2  s .  c om*/
                if (clazz.isEnum()) {
                    typedObj = Enum.valueOf(clazz, value);
                } else if (clazz == BigDecimal.class) {
                    typedObj = new BigDecimal(value);
                } else {
                    typedObj = JavaClassHelper.parse(clazz, value);
                }
                entry.getValue().setInitializationValue(typedObj);
            } catch (ClassNotFoundException ex) {
                throw new InternalEngineException("Unknown variable type: " + type);
            }
        }
    }
}

From source file:eu.europa.ec.fisheries.uvms.spatial.rest.resources.secured.AreaResource.java

@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Path("/properties")
@Interceptors(value = { ValidationInterceptor.class, ExceptionInterceptor.class })
public Response getAreaProperties(List<AreaCoordinateType> areaDtoList) throws ServiceException {
    List<AreaTypeEntry> areaTypeEntryList = null;

    if (CollectionUtils.isNotEmpty(areaDtoList)) {
        areaTypeEntryList = new ArrayList<>(areaDtoList.size());
        for (AreaCoordinateType areaCoordinateType : areaDtoList) {

            AreaTypeEntry areaTypeEntry = new AreaTypeEntry();

            areaTypeEntry.setLongitude(areaCoordinateType.getLongitude());
            areaTypeEntry.setLatitude(areaCoordinateType.getLatitude());
            areaTypeEntry.setCrs(areaCoordinateType.getCrs());
            areaTypeEntry.setId(areaCoordinateType.getId());

            areaTypeEntry//ww w.j ava2  s . c om
                    .setAreaType(Enum.valueOf(AreaType.class, areaCoordinateType.getAreaType().toUpperCase()));

            areaTypeEntryList.add(areaTypeEntry);
        }
    }

    List<Map<String, Object>> selectedAreaColumns = areaService.getAreasByIds(areaTypeEntryList);
    return createSuccessResponse(selectedAreaColumns);
}

From source file:org.apache.openjpa.persistence.JPAProperties.java

/**
 * Gets a enum value of the given type from the given value.
 * Converts the original value from a String or ordinal number, if necessary.
 * Conversion from an integral number to enum value is only attempted if the allowed enum values
 * are provided as non-null, non-empty array. 
 * // ww w  . ja  v a2 s. c  o m
 * @return null if the key does not exist in the given properties.
 */
public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, Object val) {
    if (val == null)
        return null;
    if (type.isInstance(val))
        return (E) val;
    if (val instanceof String) {
        return Enum.valueOf(type, val.toString().trim().toUpperCase());
    }
    if (values != null && values.length > 0 && val instanceof Number) {
        return values[((Number) val).intValue()];
    }
    return null;
}

From source file:org.apache.hadoop.hive.metastore.security.HadoopThriftAuthBridge.java

/**
 * Return true if the current login user is already using the given authMethod.
 *
 * Used above to ensure we do not create a new Configuration object and as such
 * lose other settings such as the cluster to which the JVM is connected. Required
 * for oozie since it does not have a core-site.xml see HIVE-7682
 *//*  w ww  . j ava  2  s .  c  om*/
private boolean loginUserHasCurrentAuthMethod(UserGroupInformation ugi, String sAuthMethod) {
    AuthenticationMethod authMethod;
    try {
        // based on SecurityUtil.getAuthenticationMethod()
        authMethod = Enum.valueOf(AuthenticationMethod.class, sAuthMethod.toUpperCase(Locale.ENGLISH));
    } catch (IllegalArgumentException iae) {
        throw new IllegalArgumentException(
                "Invalid attribute value for " + HADOOP_SECURITY_AUTHENTICATION + " of " + sAuthMethod, iae);
    }
    LOG.debug("Current authMethod = " + ugi.getAuthenticationMethod());
    return ugi.getAuthenticationMethod().equals(authMethod);
}

From source file:com.amazonaws.hal.client.ConversionUtil.java

private static Object convertFromString(Class<?> clazz, String value) {
    if (String.class.isAssignableFrom(clazz)) {
        return value;
    } else if (int.class.isAssignableFrom(clazz) || Integer.class.isAssignableFrom(clazz)) {
        return new Integer(value);
    } else if (long.class.isAssignableFrom(clazz) || Long.class.isAssignableFrom(clazz)) {
        return new Long(value);
    } else if (short.class.isAssignableFrom(clazz) || Short.class.isAssignableFrom(clazz)) {
        return new Short(value);
    } else if (double.class.isAssignableFrom(clazz) || Double.class.isAssignableFrom(clazz)) {
        return new Double(value);
    } else if (float.class.isAssignableFrom(clazz) || Float.class.isAssignableFrom(clazz)) {
        return new Float(value);
    } else if (boolean.class.isAssignableFrom(clazz) || Boolean.class.isAssignableFrom(clazz)) {
        return Boolean.valueOf(value);
    } else if (char.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz)) {
        return value.charAt(0);
    } else if (byte.class.isAssignableFrom(clazz) || Byte.class.isAssignableFrom(clazz)) {
        return new Byte(value);
    } else if (BigDecimal.class.isAssignableFrom(clazz)) {
        return new BigDecimal(value);
    } else if (BigInteger.class.isAssignableFrom(clazz)) {
        return new BigInteger(value);
    } else if (Date.class.isAssignableFrom(clazz)) {
        try {/*  w w w.j a  v a  2s .c  o  m*/
            return new Date(Long.parseLong(value));
        } catch (NumberFormatException e) {
            try {
                return DatatypeConverter.parseDateTime(value).getTime();
            } catch (IllegalArgumentException e1) {
                throw new RuntimeException("Unexpected date format: " + value
                        + ".  We currently parse xsd:datetime and milliseconds.");
            }
        }
    } else if (clazz.isEnum()) {
        try {
            //noinspection unchecked
            return Enum.valueOf((Class<Enum>) clazz, value);
        } catch (IllegalArgumentException e) {
            log.error(String.format(
                    "'%s' is not a recognized enum value for %s.  Returning default of %s instead.", value,
                    clazz.getName(), clazz.getEnumConstants()[0]));

            return clazz.getEnumConstants()[0];
        }
    } else {
        throw new RuntimeException("Not sure how to convert " + value + " to a " + clazz.getSimpleName());
    }
}

From source file:org.openmainframe.ade.impl.PropertyAnnotation.java

@SuppressWarnings({ "unchecked" })
static private void setProps(Object obj, Map<String, ? extends Object> props, Pattern filter, boolean safe)
        throws MissingPropertyException, IllegalArgumentException {
    final Class<?> annotatedClass = obj.getClass();
    final Set<String> keyset = new TreeSet<String>(props.keySet());

    for (Field field : annotatedClass.getDeclaredFields()) {
        final Property annos = field.getAnnotation(Property.class);
        if (annos != null) {
            // skip missing and non-required properties
            final String key = annos.key();
            if (!props.containsKey(key)) {
                if (annos.required()) {
                    throw new MissingPropertyException("Missing property: " + key);
                } else {
                    // no value for non-required property
                    continue;
                }//from w  ww.  j a v a  2 s . c o  m
            }

            final Class<? extends IPropertyFactory<?>> factoryClass = annos.factory();

            final Object rawVal = props.get(key);
            final Type fieldType = field.getGenericType();
            Object val = null;
            if (factoryClass != Property.NULL_PROPERTY_FACTORY.class) {
                // check if this factory is eligible for creating this property
                final Type factoryProductType = resolveActualTypeArgs(factoryClass, IPropertyFactory.class)[0];
                if (!TypeUtils.isAssignable(factoryProductType, fieldType)) {
                    throw new IllegalArgumentException("The factory provided for the field: " + field.getName()
                            + " is not compatible for creating object of type: " + fieldType);
                }

                Constructor<? extends IPropertyFactory<?>> constructor;
                try {
                    constructor = factoryClass.getConstructor();
                } catch (Exception e) {
                    throw new IllegalArgumentException(
                            "Missing empty constructor in: " + factoryClass.getName(), e);
                }

                IPropertyFactory<?> factory;
                try {
                    factory = constructor.newInstance();
                } catch (Exception e) {
                    throw new IllegalArgumentException("Failed instantiating: " + factoryClass.getName(), e);
                }

                try {
                    val = factory.create(rawVal);
                } catch (Exception e) {
                    throw new IllegalArgumentException("Failed extractring property value: " + key, e);
                }
            } else if (TypeUtils.isAssignable(rawVal.getClass(), fieldType)) {
                val = rawVal;
            } else if (rawVal.getClass().equals(String.class)) {
                final Class<?> fieldClass = field.getType();
                final String stringVal = (String) rawVal;
                if (fieldClass == Integer.class || fieldClass == int.class) {
                    try {
                        val = Integer.parseInt(stringVal);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Failed parsing integer value for property: " + key,
                                e);
                    }
                } else if (fieldClass == Double.class || fieldClass == double.class) {
                    try {
                        val = Double.parseDouble(stringVal);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Failed parsing double value for property: " + key,
                                e);
                    }
                } else if (fieldClass == Boolean.class || fieldClass == boolean.class) {
                    try {
                        val = Boolean.parseBoolean(stringVal);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Failed parsing boolean value for property: " + key,
                                e);
                    }
                } else if (fieldClass == String.class) {
                    // should never have reached here, since String is assignable from String
                    val = stringVal;
                } else if (fieldClass.isEnum()) {
                    Class<Enum> fieldEnum;
                    try {
                        fieldEnum = (Class<Enum>) fieldClass;
                    } catch (ClassCastException e) {
                        throw new IllegalArgumentException(
                                "Failed casting to Class<Enum> field class: " + fieldClass.getName(), e);
                    }
                    try {
                        val = Enum.valueOf(fieldEnum, stringVal);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Failed parsing enum value for property: " + key
                                + "\n\t possible values: " + Arrays.toString(fieldEnum.getEnumConstants()), e);
                    }
                } else {
                    // try to find String constructor for field, or else throw exception
                    Constructor<?> constructor;
                    try {
                        constructor = fieldClass.getConstructor(String.class);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Field: " + field.getName() + " of type "
                                + fieldClass
                                + " is not one of the known property type (Integer, Double, Boolean, String, Enum), does not have a String constructor and no custom factory is defined in the annotation!",
                                e);
                    }
                    try {
                        val = constructor.newInstance(stringVal);
                    } catch (Exception e) {
                        throw new IllegalArgumentException("Could not create a new instance for "
                                + field.getName() + " using the String constructor for type: " + fieldClass, e);
                    }
                }
            }

            if (val == null) {
                throw new IllegalArgumentException("For the key " + key
                        + ", we expect the value to be either assignable to " + fieldType + " or a String");
            }

            try {
                field.setAccessible(true);
                field.set(obj, val);
                keyset.remove(key);
            } catch (SecurityException e) {
                throw new SecurityException("Field " + field.getName()
                        + " is not accesible, and could not be set as accesible (probably due to PermissionManager)",
                        e);
            } catch (Exception e) {
                throw new IllegalArgumentException(
                        "Failed setting field: " + field.getName() + " with value: " + val, e);
            }
        }
    }
    if (safe && !keyset.isEmpty()) {
        throw new IllegalArgumentException("Unrecongnized arguments in the properties: " + keyset.toString());
    }
}

From source file:org.protorabbit.json.DefaultSerializer.java

@SuppressWarnings("unchecked")
void invokeMethod(Method[] methods, String key, String name, JSONObject jo, Object targetObject) {
    Object param = null;//from   w w  w .  j  av a2  s.  c om
    Throwable ex = null;
    for (int i = 0; i < methods.length; i++) {
        Method m = methods[i];
        if (m.getName().equals(name)) {
            Class<?>[] paramTypes = m.getParameterTypes();
            if (paramTypes.length == 1 && jo.has(key)) {
                Class<?> tparam = paramTypes[0];
                boolean allowNull = false;
                try {
                    if (jo.isNull(key)) {
                        // do nothing because param is already null : lets us not null on other types
                    } else if (Long.class.isAssignableFrom(tparam) || tparam == long.class) {
                        param = new Long(jo.getLong(key));
                    } else if (Double.class.isAssignableFrom(tparam) || tparam == double.class) {
                        param = new Double(jo.getDouble(key));
                    } else if (Integer.class.isAssignableFrom(tparam) || tparam == int.class) {
                        param = new Integer(jo.getInt(key));
                    } else if (String.class.isAssignableFrom(tparam)) {
                        param = jo.getString(key);
                    } else if (Enum.class.isAssignableFrom(tparam)) {
                        param = Enum.valueOf((Class<? extends Enum>) tparam, jo.getString(key));
                    } else if (Boolean.class.isAssignableFrom(tparam)) {
                        param = new Boolean(jo.getBoolean(key));
                    } else if (jo.isNull(key)) {
                        param = null;
                        allowNull = true;
                    } else if (Collection.class.isAssignableFrom(tparam)) {

                        if (m.getGenericParameterTypes().length > 0) {
                            Type t = m.getGenericParameterTypes()[0];
                            if (t instanceof ParameterizedType) {
                                ParameterizedType tv = (ParameterizedType) t;
                                if (tv.getActualTypeArguments().length > 0
                                        && tv.getActualTypeArguments()[0] == String.class) {

                                    List<String> ls = new ArrayList<String>();
                                    JSONArray ja = jo.optJSONArray(key);
                                    if (ja != null) {
                                        for (int j = 0; j < ja.length(); j++) {
                                            ls.add(ja.getString(j));
                                        }
                                    }
                                    param = ls;
                                } else if (tv.getActualTypeArguments().length == 1) {
                                    ParameterizedType type = (ParameterizedType) tv.getActualTypeArguments()[0];
                                    Class itemClass = (Class) type.getRawType();
                                    if (itemClass == Map.class && type.getActualTypeArguments().length == 2
                                            && type.getActualTypeArguments()[0] == String.class
                                            && type.getActualTypeArguments()[1] == Object.class) {

                                        List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();

                                        JSONArray ja = jo.optJSONArray(key);
                                        if (ja != null) {
                                            for (int j = 0; j < ja.length(); j++) {
                                                Map<String, Object> map = new HashMap<String, Object>();
                                                JSONObject mo = ja.getJSONObject(j);
                                                Iterator<String> keys = mo.keys();
                                                while (keys.hasNext()) {
                                                    String okey = keys.next();
                                                    Object ovalue = null;
                                                    // make sure we don't get JSONObject$Null
                                                    if (!mo.isNull(okey)) {
                                                        ovalue = mo.get(okey);
                                                    }
                                                    map.put(okey, ovalue);
                                                }
                                                ls.add(map);
                                            }
                                        }
                                        param = ls;
                                    } else {
                                        getLogger().warning(
                                                "Don't know how to handle Collection of type : " + itemClass);
                                    }

                                } else {
                                    getLogger().warning("Don't know how to handle Collection of type : "
                                            + tv.getActualTypeArguments()[0]);
                                }
                            }
                        }
                    } else {
                        getLogger().warning(
                                "Unable to serialize " + key + " :  Don't know how to handle " + tparam);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                if (param != null || allowNull) {

                    try {

                        if (m != null) {
                            Object[] args = { param };
                            m.invoke(targetObject, args);
                            ex = null;
                            break;
                        }
                    } catch (SecurityException e) {
                        ex = e;
                    } catch (IllegalArgumentException e) {
                        ex = e;
                    } catch (IllegalAccessException e) {
                        ex = e;
                    } catch (InvocationTargetException e) {
                        ex = e;
                    }
                }
            }
        }
    }
    if (ex != null) {
        if (ex instanceof RuntimeException) {
            throw (RuntimeException) ex;
        } else {
            throw new RuntimeException(ex);
        }
    }
}

From source file:io.github.wysohn.triggerreactor.tools.ReflectionUtil.java

@SuppressWarnings({ "unchecked", "unchecked" })
public static Object invokeMethod(Class<?> clazz, Object obj, String methodName, Object... args)
        throws NoSuchMethodException, IllegalArgumentException, InvocationTargetException,
        IllegalAccessException {//from   w w  w.  jav  a  2  s. c o  m
    try {
        List<Method> validMethods = new ArrayList<>();

        for (Method method : clazz.getMethods()) {
            Class<?>[] parameterTypes = null;

            if (!method.getName().equals(methodName)) {
                continue;
            }

            parameterTypes = method.getParameterTypes();
            if (method.isVarArgs()) {
                if (method.isVarArgs() && (parameterTypes.length - args.length >= 2)) {
                    parameterTypes = null;
                    continue;
                }
            } else {
                if (parameterTypes.length != args.length) {
                    parameterTypes = null;
                    continue;
                }
            }

            if (method.isVarArgs()) {
                boolean matches = false;

                // check non vararg part
                for (int i = 0; i < parameterTypes.length - 1; i++) {
                    matches = checkMatch(parameterTypes[i], args[i]);
                    if (!matches)
                        break;
                }

                // check rest
                for (int i = parameterTypes.length - 1; i < args.length; i++) {
                    Class<?> arrayType = parameterTypes[parameterTypes.length - 1].getComponentType();

                    matches = checkMatch(arrayType, args[i]);
                    if (!matches)
                        break;
                }

                if (matches) {
                    validMethods.add(method);
                }
            } else {
                boolean matches = true;

                for (int i = 0; i < parameterTypes.length; i++) {
                    matches = checkMatch(parameterTypes[i], args[i]);
                    if (!matches)
                        break;
                }

                if (matches) {
                    validMethods.add(method);
                }
            }
        }

        if (!validMethods.isEmpty()) {
            Method method = validMethods.get(0);
            for (int i = 1; i < validMethods.size(); i++) {
                Method targetMethod = validMethods.get(i);

                Class<?>[] currentParams = method.getParameterTypes();
                Class<?>[] targetParams = targetMethod.getParameterTypes();

                if (method.isVarArgs() && targetMethod.isVarArgs()) {
                    for (int j = 0; j < currentParams.length; j++) {
                        if (currentParams[j].isAssignableFrom(targetParams[j])) {
                            method = targetMethod;
                            break;
                        }
                    }
                } else if (method.isVarArgs()) {
                    //usually, non-vararg is more specific method. So we use that
                    method = targetMethod;
                } else if (targetMethod.isVarArgs()) {
                    //do nothing
                } else {
                    for (int j = 0; j < currentParams.length; j++) {
                        if (targetParams[j].isEnum()) { // enum will be handled later
                            method = targetMethod;
                            break;
                        } else if (ClassUtils.isAssignable(targetParams[j], currentParams[j], true)) { //narrow down to find the most specific method
                            method = targetMethod;
                            break;
                        }
                    }
                }
            }

            method.setAccessible(true);

            for (int i = 0; i < args.length; i++) {
                Class<?>[] parameterTypes = method.getParameterTypes();

                if (args[i] instanceof String && i < parameterTypes.length && parameterTypes[i].isEnum()) {
                    try {
                        args[i] = Enum.valueOf((Class<? extends Enum>) parameterTypes[i], (String) args[i]);
                    } catch (IllegalArgumentException ex1) {
                        // Some overloaded methods already has
                        // String to Enum conversion
                        // So just lets see if one exists
                        Class<?>[] types = new Class<?>[args.length];
                        for (int k = 0; k < args.length; k++)
                            types[k] = args[k].getClass();

                        try {
                            Method alternative = clazz.getMethod(methodName, types);
                            return alternative.invoke(obj, args);
                        } catch (NoSuchMethodException ex2) {
                            throw new RuntimeException(
                                    "Tried to convert value [" + args[i] + "] to Enum [" + parameterTypes[i]
                                            + "] or find appropriate method but found nothing. Make sure"
                                            + " that the value [" + args[i]
                                            + "] matches exactly with one of the Enums in [" + parameterTypes[i]
                                            + "] or the method you are looking exists.");
                        }
                    }
                }
            }

            if (method.isVarArgs()) {
                Class<?>[] parameterTypes = method.getParameterTypes();

                Object varargs = Array.newInstance(parameterTypes[parameterTypes.length - 1].getComponentType(),
                        args.length - parameterTypes.length + 1);
                for (int k = 0; k < Array.getLength(varargs); k++) {
                    Array.set(varargs, k, args[parameterTypes.length - 1 + k]);
                }

                Object[] newArgs = new Object[parameterTypes.length];
                for (int k = 0; k < newArgs.length - 1; k++) {
                    newArgs[k] = args[k];
                }
                newArgs[newArgs.length - 1] = varargs;

                args = newArgs;
            }

            return method.invoke(obj, args);
        }

        if (args.length > 0) {
            StringBuilder builder = new StringBuilder(String.valueOf(args[0].getClass().getSimpleName()));

            for (int i = 1; i < args.length; i++) {
                builder.append(", " + args[i].getClass().getSimpleName());
            }

            throw new NoSuchMethodException(methodName + "(" + builder.toString() + ")");
        } else {
            throw new NoSuchMethodException(methodName + "()");
        }
    } catch (NullPointerException e) {
        StringBuilder builder = new StringBuilder(String.valueOf(args[0]));
        for (int i = 1; i < args.length; i++)
            builder.append("," + String.valueOf(args[i]));
        throw new NullPointerException("Call " + methodName + "(" + builder.toString() + ")");
    }
}

From source file:com.intuit.wasabi.api.pagination.comparators.PaginationComparator.java

/**
 * Compares two objects by this instance's sort order.
 * <p>//from  w w  w .  j  a v a2s .  c  o m
 * Splits the sort order on {@code ,} and tries to sort by each of the supplied fields.
 * The strings obtained after splitting must be valid keys for {@code enumType} (or valid keys
 * prefixed with a hyphen {@code -} for descending order), otherwise the sorting fails and a
 * {@link PaginationException} is thrown with {@link ErrorCode#SORT_KEY_UNPROCESSABLE}.
 * <p>
 * The comparison in general follows {@link java.util.Comparator#compare(Object, Object)},
 * where depending on how the comparison logic is implemented by the passed
 * {@code enumType} of type {@link PaginationComparatorProperty}.
 * <p>
 * This method returns either -1, 0, or 1:
 * <dl>
 * <dt>-1</dt>
 * <dd>If the right object should appear after the left object.</dd>
 * <dt>0</dt>
 * <dd>If the order of the two given object is unimportant, that means for
 * the given sort order they are considered to be equal. This is the default.</dd>
 * <dt>1</dt>
 * <dd>If the left object should appear after the right object.</dd>
 * </dl>
 * <p>
 * If one objects value for a sort key is null, it will always be sorted after the other object.
 * See {@link #compareNull(Object, Object, boolean)} for more details on this.
 * Additionally if the first key in the sort order suffices, the comparison follows the fail-fast
 * principle and returns the value. Otherwise it sorts as long as needed to break the tie between
 * the two objects.
 * <p>
 * For information on how to implement the {@code enumType}, take a look at the examples at
 * {@link PaginationComparator} or {@link PaginationComparatorProperty}.
 *
 * @param left     left object
 * @param right    right object
 * @param enumType an enum implementing {@link PaginationComparatorProperty}
 * @param <V>      The enum type implementing {@link PaginationComparatorProperty}
 * @return -1, 0, 1, see above for more details.
 * @see #compareNull(Object, Object, boolean)
 * @see #compareByProperty(Object, Object, Function, BiFunction, boolean)
 */
protected <V extends Enum<V> & PaginationComparatorProperty> int compare(T left, T right, Class<V> enumType) {
    for (String sort : sortOrder.toLowerCase().split(",")) {
        boolean descending = sort.startsWith("-");

        String propertyKey = descending ? sort.substring(1) : sort;

        if (StringUtils.isBlank(propertyKey)) {
            continue;
        }

        V property;
        try {
            property = Enum.valueOf(enumType, propertyKey);
        } catch (IllegalArgumentException illegalArgumentException) {
            throw new PaginationException(ErrorCode.SORT_KEY_UNPROCESSABLE,
                    "The request can not be sorted by " + propertyKey, illegalArgumentException);
        }

        int result = compareByProperty(left, right, property.getPropertyExtractor(),
                property.getComparisonFunction(), descending);
        if (result != 0) {
            return result;
        }
    }
    return 0;
}