Class BeanUtils

  • All Implemented Interfaces:
    Utils

    public abstract class BeanUtils
    extends java.lang.Object
    implements Utils
    The utilities class for Java Beans
    Since:
    1.0.0
    Author:
    Mercy
    See Also:
    Utils
    • Field Detail

      • BEAN_PROPERTIES_MAX_RESOLVED_DEPTH_PROPERTY_NAME

        public static final java.lang.String BEAN_PROPERTIES_MAX_RESOLVED_DEPTH_PROPERTY_NAME
        The property name for the maximum depth of resolving properties of a bean.

        This property is used to configure the maximum depth to which nested properties of a Java Bean will be resolved. This helps in preventing stack overflow errors when dealing with deeply nested objects. The default value is defined by DEFAULT_BEAN_PROPERTIES_MAX_RESOLVED_DEPTH_PROPERTY_VALUE.

        Example Usage

        
         // Setting the system property to limit the resolution depth
         System.setProperty(BEAN_PROPERTIES_MAX_RESOLVED_DEPTH_PROPERTY_NAME, "50");
         
        See Also:
        Constant Field Values
      • DEFAULT_BEAN_PROPERTIES_MAX_RESOLVED_DEPTH

        public static final int DEFAULT_BEAN_PROPERTIES_MAX_RESOLVED_DEPTH
        The default maximum levels of resolving properties of a bean, default is 100
      • BEAN_PROPERTIES_MAX_RESOLVED_DEPTH

        @ConfigurationProperty(name="microsphere.bean.properties.max-resolved-depth",
                               defaultValue="100",
                               description="The maximum depth of resolving properties of a bean in order to avoid stack overflow, default is 100")
        public static final int BEAN_PROPERTIES_MAX_RESOLVED_DEPTH
        The maximum levels of resolving properties of a bean, default is 100
      • DEFAULT_BEAN_METADATA_CACHE_SIZE

        public static final int DEFAULT_BEAN_METADATA_CACHE_SIZE
        The default cache size of BeanMetadata, default value : 64
      • BEAN_METADATA_CACHE_SIZE_PROPERTY_NAME

        public static final java.lang.String BEAN_METADATA_CACHE_SIZE_PROPERTY_NAME
        The property name of cache size of BeanMetadata : "microsphere.bean.metadata.cache.size"
        See Also:
        Constant Field Values
    • Method Detail

      • resolvePropertiesAsMap

        @Nonnull
        @Immutable
        public static java.util.Map<java.lang.String,​java.lang.Object> resolvePropertiesAsMap​(java.lang.Object bean)
        Resolves the properties of a given Java Bean and returns them as a Map.

        This method introspects the provided bean, extracts its properties using PropertyDescriptors, and constructs a map where each key is the uncapitalized property name and each value is the resolved property value. The resolution process handles nested objects, arrays, lists, sets, and maps recursively up to a maximum depth defined by BEAN_PROPERTIES_MAX_RESOLVED_DEPTH.

        Example Usage

        
         public class Person {
             private String name;
             private Address address;
        
             // Getters and setters...
         }
        
         public class Address {
             private String city;
        
             // Getters and setters...
         }
        
         Person person = new Person();
         person.setName("John Doe");
         Address address = new Address();
         address.setCity("New York");
         person.setAddress(address);
        
         Map<String, Object> properties = BeanUtils.resolvePropertiesAsMap(person);
         // Resulting map:
         // {
         //   "name": "John Doe",
         //   "address": {
         //     "city": "New York"
         //   }
         // }
         
        Parameters:
        bean - the Java Bean whose properties are to be resolved; may be null
        Returns:
        an unmodifiable Map containing the resolved properties, or an empty map if the bean is null or maximum resolution depth is reached
        See Also:
        resolvePropertiesAsMap(Object, int), BEAN_PROPERTIES_MAX_RESOLVED_DEPTH
      • resolvePropertiesAsMap

        @Nonnull
        @Immutable
        public static java.util.Map<java.lang.String,​java.lang.Object> resolvePropertiesAsMap​(java.lang.Object bean,
                                                                                                    int maxResolvedDepth)
        Resolves the properties of a given Java Bean up to a specified maximum depth and returns them as a Map.

        This method introspects the provided bean, extracts its properties using PropertyDescriptors, and constructs a map where each key is the uncapitalized property name and each value is the resolved property value. The resolution process handles nested objects, arrays, lists, sets, and maps recursively, but will stop resolving further once the specified maxResolvedDepth is reached.

        Example Usage

        
         public class Person {
             private String name;
             private Address address;
        
             // Getters and setters...
         }
        
         public class Address {
             private String city;
             private Country country;
        
             // Getters and setters...
         }
        
         public class Country {
             private String name;
        
             // Getters and setters...
         }
        
         Person person = new Person();
         person.setName("John Doe");
         Address address = new Address();
         address.setCity("New York");
         Country country = new Country();
         country.setName("USA");
         address.setCountry(country);
         person.setAddress(address);
        
         Map<String, Object> properties = BeanUtils.resolvePropertiesAsMap(person, 2);
         // Resulting map (depth limited to 2):
         // {
         //   "name": "John Doe",
         //   "address": {
         //     "city": "New York",
         //     "country": {}  // country's properties not resolved due to depth limit
         //   }
         // }
         
        Parameters:
        bean - the Java Bean whose properties are to be resolved; may be null
        maxResolvedDepth - the maximum depth to which nested properties should be resolved; must be non-negative
        Returns:
        an unmodifiable Map containing the resolved properties, or an empty map if the bean is null or maximum resolution depth is reached
        Throws:
        java.lang.IllegalArgumentException - if maxResolvedDepth is negative
        See Also:
        resolvePropertiesAsMap(Object), resolvePropertiesAsMap(Object, MutableInteger, int)
      • getBeanMetadata

        @Nonnull
        public static BeanMetadata getBeanMetadata​(java.lang.Class<?> beanClass)
                                            throws java.lang.RuntimeException
        Get the BeanMetadata for the specified Class.
        Parameters:
        beanClass - the specified Class
        Returns:
        non-null
        Throws:
        java.lang.RuntimeException - if an exception occurs during introspection
      • findWriteMethod

        public static java.lang.reflect.Method findWriteMethod​(BeanMetadata beanMetadata,
                                                               java.lang.String propertyName)
        Finds the write method (setter) for a specified property of a given bean.

        This method retrieves the PropertyDescriptor for the specified property from the provided BeanMetadata. If the property descriptor exists and has a write method, that method is returned. Otherwise, null is returned.

        Example Usage

        
         // Example 1: Finding a write method for a simple property
         BeanMetadata metadata = BeanMetadata.of(Person.class);
         Method setNameMethod = BeanUtils.findWriteMethod(metadata, "name");
         if (setNameMethod != null) {
             System.out.println("Found setter method: " + setNameMethod.getName());
         }
        
         // Example 2: Handling a property with no setter
         Method readOnlyPropertyMethod = BeanUtils.findWriteMethod(metadata, "readOnlyProperty");
         if (readOnlyPropertyMethod == null) {
             System.out.println("No setter method found for 'readOnlyProperty'");
         }
         
        Parameters:
        beanMetadata - the metadata of the bean to introspect; must not be null
        propertyName - the name of the property for which to find the write method; must not be null or empty
        Returns:
        the write method (setter) for the specified property, or null if no such method exists or the property is not found
        Throws:
        java.lang.IllegalArgumentException - if beanMetadata or propertyName is null
      • findPropertyDescriptor

        public static java.beans.PropertyDescriptor findPropertyDescriptor​(BeanMetadata beanMetadata,
                                                                           java.lang.String propertyName)
        Finds the PropertyDescriptor for a specified property of a given bean.

        This method retrieves the PropertyDescriptor for the specified property from the provided BeanMetadata. If the property descriptor exists, it is returned. Otherwise, null is returned. If the property descriptor is not found, a trace log message will be recorded.

        Example Usage

        
         // Example 1: Finding a property descriptor for a simple property
         BeanMetadata metadata = BeanMetadata.of(Person.class);
         PropertyDescriptor nameDescriptor = BeanUtils.findPropertyDescriptor(metadata, "name");
         if (nameDescriptor != null) {
             System.out.println("Found property descriptor: " + nameDescriptor.getName());
         }
        
         // Example 2: Handling a non-existent property
         PropertyDescriptor nonExistentDescriptor = BeanUtils.findPropertyDescriptor(metadata, "nonExistentProperty");
         if (nonExistentDescriptor == null) {
             System.out.println("Property descriptor not found for 'nonExistentProperty'");
         }
         
        Parameters:
        beanMetadata - the metadata of the bean to introspect; must not be null
        propertyName - the name of the property for which to find the descriptor; must not be null or empty
        Returns:
        the PropertyDescriptor for the specified property, or null if no such descriptor exists or the property is not found
        Throws:
        java.lang.IllegalArgumentException - if beanMetadata or propertyName is null
      • resolvePropertiesAsMap

        @Nonnull
        @Immutable
        protected static java.util.Map<java.lang.String,​java.lang.Object> resolvePropertiesAsMap​(java.lang.Object bean,
                                                                                                       MutableInteger resolvedDepth,
                                                                                                       int maxResolvedDepth)
        Resolves the properties of a given Java Bean recursively up to a specified maximum depth, tracking the current depth with a MutableInteger, and returns them as a Map.

        This method introspects the provided bean, extracts its properties using PropertyDescriptors, and constructs a map where each key is the uncapitalized property name and each value is the resolved property value. The resolution process handles nested objects, arrays, lists, sets, and maps recursively, but will stop resolving further once the specified maxResolvedDepth is reached. The resolvedDepth parameter is used to track the current depth of recursion and is incremented upon each call.

        Example Usage

        
         public class Person {
             private String name;
             private Address address;
        
             // Getters and setters...
         }
        
         public class Address {
             private String city;
             private Country country;
        
             // Getters and setters...
         }
        
         public class Country {
             private String name;
        
             // Getters and setters...
         }
        
         Person person = new Person();
         person.setName("John Doe");
         Address address = new Address();
         address.setCity("New York");
         Country country = new Country();
         country.setName("USA");
         address.setCountry(country);
         person.setAddress(address);
        
         MutableInteger depth = MutableInteger.of(0);
         Map<String, Object> properties = BeanUtils.resolvePropertiesAsMap(person, depth, 3);
         // Resulting map (depth limited to 3):
         // {
         //   "name": "John Doe",
         //   "address": {
         //     "city": "New York",
         //     "country": {
         //       "name": "USA"
         //     }
         //   }
         // }
         
        Parameters:
        bean - the Java Bean whose properties are to be resolved; may be null
        resolvedDepth - the current depth of property resolution, incremented on each recursive call; must not be null
        maxResolvedDepth - the maximum depth to which nested properties should be resolved; must be non-negative
        Returns:
        an unmodifiable Map containing the resolved properties, or an empty map if the bean is null or maximum resolution depth is reached
        Throws:
        java.lang.IllegalArgumentException - if maxResolvedDepth is negative
        See Also:
        resolvePropertiesAsMap(Object), resolvePropertiesAsMap(Object, int)