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

org.eclipse.persistence.internal.helper.PropertiesUtils Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2015, 2024 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2015 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     02/19/2015 - Rick Curtis
//       - 458877 : Add national character support
//     03/06/2015-2.7.0 Dalia Abo Sheasha
//       - 461607: PropertiesUtils does not process methods with String parameters correctly.
//     05/06/2015-2.7.0 Rick Curtis
//       - 466626: Fix bug in getMethods() when Java 2 security is enabled.
package org.eclipse.persistence.internal.helper;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;

/**
 * A static utility class that handles parsing a String
 * "key=value,key1=value1...." and calls an appropriate set[key]([value]) method
 * on the provided instance.
 */
public class PropertiesUtils {
    /**
     * Attempts to parse and then set the provided kvs String into the
     * appropriate set method on the provided instance.
     *
     * Note: Keys and values cannot contain '=' or ','
     *
     * @param instance
     *            An JavaBean instance
     * @param propertyName
     *            The configuration name that is being set into instance. This
     *            is only used for informational purposes.
     * @param kvs
     *            A String of key=value comma delimited ie: k1=v1,k2=v2,...
     * @throws org.eclipse.persistence.exceptions.ConversionException
     *             if unable to process the provided kvs
     */
    public static void set(Object instance, String propertyName, String kvs) {
        if (instance == null || kvs == null || kvs.trim().isEmpty()) {
            return;
        }
        String[] keyValues = kvs.split(",");
        for (String kv : keyValues) {
            processKeyValue(instance, propertyName, kv);
        }
    }

    private static void processKeyValue(Object instance, String propertyName, String kv) {
        String[] t = kv.split("=");

        if (t.length != 2) {
            // We must have a single key and a single value.
            throw ConversionException.couldNotTranslatePropertiesIntoObject(instance, propertyName, kv, null);
        }
        String methodName = "set" + t[0].trim();
        // Stringified value to be set. Need to figure out it's type
        String value = t[1].trim();
        List methods = getMethodsMatchingName(instance, methodName);
        MethodMatch match = null;
        try {
            match = getMethodMatchingParameter(methods, value);
        } catch (Exception e) {
            throw ConversionException.couldNotTranslatePropertiesIntoObject(instance, propertyName, kv, e);
        }
        if (match != null) {
            Method method = match.getMethod();
            Object parsedValue = match.getParsedValue();
            try {
                invokeMethod(method, instance, parsedValue);
            } catch (Exception e) {
                throw ConversionException.couldNotTranslatePropertiesIntoObject(instance, propertyName, kv, e);
            }
        } else {
            throw ConversionException.couldNotTranslatePropertiesIntoObject(instance, propertyName, kv, null);
        }
    }

    private static MethodMatch getMethodMatchingParameter(List methods, String parameter) throws Exception {
        Object parsedParameterValue = null;
        Method res = null;
        for (Method method : methods) {
            Class[] params = method.getParameterTypes();
            if (params.length == 1) {
                Class param = params[0];
                if (param == String.class) {
                    parsedParameterValue = parameter;
                } else if (param == Integer.class || param == int.class) {
                    parsedParameterValue = Integer.parseInt(parameter);
                } else if (param == Boolean.class || param == boolean.class) {
                    // Don't use Boolean.parseBoolean(..) as it is to liberal
                    // with it's interpretation of false values
                    String lower = parameter.toLowerCase();
                    if ("true".equals(lower)) {
                        parsedParameterValue = Boolean.TRUE;
                    } else if ("false".equals(lower)) {
                        parsedParameterValue = Boolean.FALSE;
                    }
                } else if (param == Long.class || param == long.class) {
                    parsedParameterValue = Long.parseLong(parameter);
                } else if (param == Float.class || param == float.class) {
                    parsedParameterValue = Float.parseFloat(parameter);
                } else if (param == Double.class || param == double.class) {
                    parsedParameterValue = Double.parseDouble(parameter);
                }
            }
            if (parsedParameterValue != null) {
                return new MethodMatch(method, parsedParameterValue);
            }
        }// end for
        return null;
    }

    private static List getMethodsMatchingName(Object instance, String methodName) {
        List methods = new ArrayList<>();
        for (Method method : getMethods(instance.getClass())) {
            if (method.getName().equalsIgnoreCase(methodName)) {
                methods.add(method);
            }
        }
        return methods;
    }

    private static Method[] getMethods(Class cls) {
        return PrivilegedAccessHelper.callDoPrivileged(
                () -> PrivilegedAccessHelper.getMethods(cls)
        );
    }

    private static Object invokeMethod(Method method, Object instance, Object... params) throws Exception {
        return PrivilegedAccessHelper.callDoPrivilegedWithException(
                () -> PrivilegedAccessHelper.invokeMethod(method, instance, params)
        );
    }

    private static class MethodMatch {
        final Method method;
        final Object parsedValue;

        public MethodMatch(Method m, Object p) {
            method = m;
            parsedValue = p;
        }

        public Method getMethod() {
            return method;
        }

        public Object getParsedValue() {
            return parsedValue;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy