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

com.github.edgar615.util.reflect.PropertyDescriptorCache Maven / Gradle / Ivy

The newest version!
package com.github.edgar615.util.reflect;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * PropertyDescriptor的缓存.
 *
 * @param  泛型
 *
 * 来源于de.cronn.reflection.util,做了一些改动,删除了一些我不会用的方法.
 */
class PropertyDescriptorCache {

  private final Class type;

  /**
   * 按照属性名称的缓存
   */
  private final Map propertyDescriptorsByName = new LinkedHashMap<>();

  /**
   * 按照属性Field的缓存
   */
  private final Map propertyDescriptorsByField = new LinkedHashMap<>();

  /**
   * 按照Method的缓存
   */
  private final Map propertyDescriptorsByMethod = new LinkedHashMap<>();

  /**
   * Getter的缓存
   */
  private final Map getterByName = new LinkedHashMap<>();

  /**
   * Setter的缓存
   */
  private final Map setterByName = new LinkedHashMap<>();

  /**
   * 按照注解的缓存
   */
  private final Map, Map> propertyDescriptorsByAnnotation = new LinkedHashMap<>();

  private PropertyDescriptorCache(Class type) {
    this.type = type;

    for (PropertyDescriptor propertyDescriptor : getAllPropertyDescriptors()) {
      propertyDescriptorsByName.put(propertyDescriptor.getName(), propertyDescriptor);

      Method readMethod = propertyDescriptor.getReadMethod();
      if (readMethod != null) {
        propertyDescriptorsByMethod.put(readMethod, propertyDescriptor);
        getterByName.put(propertyDescriptor.getName(), readMethod);
        putAnnotations(propertyDescriptor, readMethod.getAnnotations());
      }

      Method writeMethod = propertyDescriptor.getWriteMethod();
      if (writeMethod != null) {
        propertyDescriptorsByMethod.put(writeMethod, propertyDescriptor);
        setterByName.put(propertyDescriptor.getName(), writeMethod);
        putAnnotations(propertyDescriptor, writeMethod.getAnnotations());
      }
    }

    for (Field field : ReflectUtils.getFields(type, true)) {
      PropertyDescriptor propertyDescriptor = propertyDescriptorsByName.get(field.getName());
      if (propertyDescriptor != null) {
        propertyDescriptorsByField.put(field, propertyDescriptor);
        putAnnotations(propertyDescriptor, field.getAnnotations());
      }
    }
  }

  static  PropertyDescriptorCache create(Class type) {
    return new PropertyDescriptorCache<>(type);
  }

  PropertyDescriptor getDescriptorByName(String propertyName) {
    return propertyDescriptorsByName.get(propertyName);
  }

  PropertyDescriptor getDescriptorByMethod(Method method) {
    return propertyDescriptorsByMethod.get(method);
  }

  PropertyDescriptor getDescriptorByField(Field field) {
    return propertyDescriptorsByField.get(field);
  }

   Map getDescriptorsForAnnotation(
      Class annotationClass) {
    @SuppressWarnings("unchecked")
    Map descriptors = (Map) propertyDescriptorsByAnnotation
        .getOrDefault(
            annotationClass, Collections.emptyMap());
    return Collections.unmodifiableMap(descriptors);
  }

  private void putAnnotations(PropertyDescriptor propertyDescriptor, Annotation[] annotations) {
    for (Annotation annotation : annotations) {
      propertyDescriptorsByAnnotation
          .computeIfAbsent(annotation.annotationType(), k -> new LinkedHashMap<>()) //
          .put(propertyDescriptor, annotation);
    }
  }

  Set getFields() {
    return propertyDescriptorsByField.keySet();
  }

  Set getMethods() {
    return propertyDescriptorsByMethod.keySet();
  }

  Map getPropertyDescriptorsByName() {
    return propertyDescriptorsByName;
  }

  Map getPropertyDescriptorsByField() {
    return propertyDescriptorsByField;
  }

  Map getPropertyDescriptorsByMethod() {
    return propertyDescriptorsByMethod;
  }

  Map getGetterByName() {
    return getterByName;
  }

  Map getSetterByName() {
    return setterByName;
  }

  Map, Map> getPropertyDescriptorsByAnnotation() {
    return propertyDescriptorsByAnnotation;
  }

  private PropertyDescriptor[] getAllPropertyDescriptors() {
    try {
      PropertyDescriptor[] descriptors = Introspector.getBeanInfo(type).getPropertyDescriptors();
      // defensive copy to prevent modification of beanutils' internals
      descriptors = Arrays.copyOf(descriptors, descriptors.length);
      Arrays.sort(descriptors, Comparator.comparing(PropertyDescriptor::getName));
      return descriptors;
    } catch (IntrospectionException e) {
      throw new ReflectionException(e);
    }
  }

  Collection getDescriptors() {
    return propertyDescriptorsByName.values();
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy