<commit_before>package com.firefly.utils;

import com.firefly.utils.function.Func1;
import com.firefly.utils.function.Func2;
import com.firefly.utils.lang.GenericTypeReference;
import com.firefly.utils.lang.bean.*;

import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.firefly.utils.ReflectUtils.*;

/**
 * @author <NAME>
 */
abstract public class BeanUtils {

    public static final Type[] EMPTY_TYPE_ARRAY = new Type[0];

    private static final ConcurrentHashMap<String, Map<String, MethodGenericTypeBind>> genericGetterCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map<String, MethodGenericTypeBind>> genericSetterCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map<String, FieldGenericTypeBind>> genericPropertyCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map<String, PropertyAccess>> genericBeanAccessCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<Class<?>, Map<String, PropertyAccess>> classBeanAccessCache = new ConcurrentHashMap<>();

    public static boolean isArray(Type type) {
        if (type instanceof Class<?>) {
            return ((Class<?>) type).isArray();
        } else if (type instanceof ParameterizedType) {
            return isArray(((ParameterizedType) type).getRawType());
        } else {
            return type instanceof GenericArrayType;
        }
    }

    public static Class<?> getComponentType(Type type) {
        if (type instanceof Class<?>) {
            return ((Class<?>) type).getComponentType();
        } else if (type instanceof ParameterizedType) {
            return getComponentType(((ParameterizedType) type).getRawType());
        } else if (type instanceof GenericArrayType) {
            return extractGenericArrayClass((GenericArrayType) type);
        } else {
            return null;
        }
    }

    public static Class<?> extractGenericArrayClass(GenericArrayType genericArrayType) {
        Type componentType = genericArrayType.getGenericComponentType();
        if (componentType instanceof Class<?>) {
            return (Class<?>) componentType;
        } else if (componentType instanceof ParameterizedType) {
            return (Class<?>) ((ParameterizedType) componentType).getRawType();
        } else if (componentType instanceof GenericArrayType) {
            return Array.newInstance(extractGenericArrayClass((GenericArrayType) componentType), 0).getClass();
        } else {
            return null;
        }
    }

    public static Class<?> extractClass(Type type) {
        if (isArray(type)) {
            return getComponentType(type);
        } else {
            if (type instanceof Class<?>) {
                return (Class<?>) type;
            } else if (type instanceof ParameterizedType) {
                return extractClass(((ParameterizedType) type).getRawType());
            } else {
                return null;
            }
        }
    }

    public static Map<String, PropertyAccess> getBeanAccess(Class<?> clazz) {
        return classBeanAccessCache.computeIfAbsent(clazz, k -> {
            Map<String, FieldGenericTypeBind> fields = getGenericBeanFields(clazz, null);
            Map<String, MethodGenericTypeBind> getters = getGenericBeanMethods(clazz, null, ReflectUtils::getGetterMethods, Method::getGenericReturnType);
            Map<String, MethodGenericTypeBind> setters = getGenericBeanMethods(clazz, null, ReflectUtils::getSetterMethods, method -> method.getGenericParameterTypes()[0]);
            return createPropertyAccessMap(fields, getters, setters);
        });
    }

    public static Map<String, PropertyAccess> getBeanAccess(GenericTypeReference genericTypeReference) {
        return genericBeanAccessCache.computeIfAbsent(genericTypeReference.getType().getTypeName(), k -> {
            Map<String, FieldGenericTypeBind> fields = getGenericBeanFields(genericTypeReference);
            Map<String, MethodGenericTypeBind> getters = getGenericBeanGetterMethods(genericTypeReference);
            Map<String, MethodGenericTypeBind> setters = getGenericBeanSetterMethods(genericTypeReference);
            return createPropertyAccessMap(fields, getters, setters);
        });
    }

    private static Map<String, PropertyAccess> createPropertyAccessMap(Map<String, FieldGenericTypeBind> fields,
                                                                       Map<String, MethodGenericTypeBind> getters,
                                                                       Map<String, MethodGenericTypeBind> setters) {
        Set<String> properties = new HashSet<>();
        properties.addAll(fields.keySet());
        properties.addAll(getters.keySet());
        properties.addAll(setters.keySet());

        Map<String, PropertyAccess> map = new HashMap<>();
        properties.forEach(name -> {
            PropertyAccessImpl propertyAccess = new PropertyAccessImpl();
            propertyAccess.setName(name);
            FieldGenericTypeBind fieldGenericTypeBind = fields.get(name);
            if (fieldGenericTypeBind != null) {
                propertyAccess.setField(fieldGenericTypeBind.getField());
                propertyAccess.setFieldProxy(getFieldProxy(fieldGenericTypeBind.getField()));
                propertyAccess.setType(fieldGenericTypeBind.getType());
            }

            MethodGenericTypeBind getter = getters.get(name);
            if (getter != null) {
                propertyAccess.setGetterMethod(getter.getMethod());
                propertyAccess.setGetterMethodProxy(getMethodProxy(getter.getMethod()));
                propertyAccess.setType(getter.getType());
            }<commit_msg>[refactor]: extract method getBeanAccessByType<commit_after>package com.firefly.utils;

import com.firefly.utils.function.Func1;
import com.firefly.utils.function.Func2;
import com.firefly.utils.lang.GenericTypeReference;
import com.firefly.utils.lang.bean.*;

import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.firefly.utils.ReflectUtils.*;

/**
 * @author <NAME>
 */
abstract public class BeanUtils {

    public static final Type[] EMPTY_TYPE_ARRAY = new Type[0];

    private static final ConcurrentHashMap<String, Map<String, MethodGenericTypeBind>> genericGetterCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map<String, MethodGenericTypeBind>> genericSetterCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map<String, FieldGenericTypeBind>> genericPropertyCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, Map<String, PropertyAccess>> genericBeanAccessCache = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<Class<?>, Map<String, PropertyAccess>> classBeanAccessCache = new ConcurrentHashMap<>();

    public static boolean isArray(Type type) {
        if (type instanceof Class<?>) {
            return ((Class<?>) type).isArray();
        } else if (type instanceof ParameterizedType) {
            return isArray(((ParameterizedType) type).getRawType());
        } else {
            return type instanceof GenericArrayType;
        }
    }

    public static Class<?> getComponentType(Type type) {
        if (type instanceof Class<?>) {
            return ((Class<?>) type).getComponentType();
        } else if (type instanceof ParameterizedType) {
            return getComponentType(((ParameterizedType) type).getRawType());
        } else if (type instanceof GenericArrayType) {
            return extractGenericArrayClass((GenericArrayType) type);
        } else {
            return null;
        }
    }

    public static Class<?> extractGenericArrayClass(GenericArrayType genericArrayType) {
        Type componentType = genericArrayType.getGenericComponentType();
        if (componentType instanceof Class<?>) {
            return (Class<?>) componentType;
        } else if (componentType instanceof ParameterizedType) {
            return (Class<?>) ((ParameterizedType) componentType).getRawType();
        } else if (componentType instanceof GenericArrayType) {
            return Array.newInstance(extractGenericArrayClass((GenericArrayType) componentType), 0).getClass();
        } else {
            return null;
        }
    }

    public static Class<?> extractClass(Type type) {
        if (isArray(type)) {
            return getComponentType(type);
        } else {
            if (type instanceof Class<?>) {
                return (Class<?>) type;
            } else if (type instanceof ParameterizedType) {
                return extractClass(((ParameterizedType) type).getRawType());
            } else {
                return null;
            }
        }
    }

    public static Map<String, PropertyAccess> getBeanAccess(Class<?> clazz) {
        return classBeanAccessCache.computeIfAbsent(clazz, k -> getBeanAccessByType(clazz));
    }

    public static Map<String, PropertyAccess> getBeanAccess(GenericTypeReference genericTypeReference) {
        return genericBeanAccessCache.computeIfAbsent(genericTypeReference.getType().getTypeName(), k -> getBeanAccessByType(genericTypeReference.getType()));
    }

    public static Map<String, PropertyAccess> getBeanAccessByType(Type type) {
        Map<String, FieldGenericTypeBind> fields = getGenericBeanFields(type, null);
        Map<String, MethodGenericTypeBind> getters = getGenericBeanMethods(type, null, ReflectUtils::getGetterMethods, Method::getGenericReturnType);
        Map<String, MethodGenericTypeBind> setters = getGenericBeanMethods(type, null, ReflectUtils::getSetterMethods, method -> method.getGenericParameterTypes()[0]);
        return createPropertyAccessMap(fields, getters, setters);
    }

    private static Map<String, PropertyAccess> createPropertyAccessMap(Map<String, FieldGenericTypeBind> fields,
                                                                       Map<String, MethodGenericTypeBind> getters,
                                                                       Map<String, MethodGenericTypeBind> setters) {
        Set<String> properties = new HashSet<>();
        properties.addAll(fields.keySet());
        properties.addAll(getters.keySet());
        properties.addAll(setters.keySet());

        Map<String, PropertyAccess> map = new HashMap<>();
        properties.forEach(name -> {
            PropertyAccessImpl propertyAccess = new PropertyAccessImpl();
            propertyAccess.setName(name);
            FieldGenericTypeBind fieldGenericTypeBind = fields.get(name);
            if (fieldGenericTypeBind != null) {
                propertyAccess.setField(fieldGenericTypeBind.getField());
                propertyAccess.setFieldProxy(getFieldProxy(fieldGenericTypeBind.getField()));
                propertyAccess.setType(fieldGenericTypeBind.getType());
            }

            MethodGenericTypeBind getter = getters.get(name);
            if (getter != null) {
                propertyAccess.setGetterMethod(getter.getMethod());
                propertyAccess.setGetterMethodProxy(getMethodProxy(getter.getMethod()));
                propertyAccess.setType(getter.getType());
            }
{'fraction_non_alphanumeric': 0.10026315789473685, 'fraction_numerical': 0.0008771929824561404, 'mean_word_length': 3.0414746543778803, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3954562', 'n_tokens_mistral': 2737, 'n_tokens_neox': 2738, 'n_words': 607}