/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.beanutils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

An internally used helper class for storing introspection information about a bean class.

This class is used by PropertyUtilsBean. When accessing bean properties via reflection information about the properties available and their types and access methods must be present. PropertyUtilsBean stores this information in a cache so that it can be accessed quickly. The cache stores instances of this class.

This class mainly stores information about the properties of a bean class. Per default, this is contained in PropertyDescriptor objects. Some additional information required by the BeanUtils library is also stored here.

Version:$Id$
Since:1.9.1
/** * <p> * An internally used helper class for storing introspection information about a bean * class. * </p> * <p> * This class is used by {@link PropertyUtilsBean}. When accessing bean properties via * reflection information about the properties available and their types and access * methods must be present. {@code PropertyUtilsBean} stores this information in a cache * so that it can be accessed quickly. The cache stores instances of this class. * </p> * <p> * This class mainly stores information about the properties of a bean class. Per default, * this is contained in {@code PropertyDescriptor} objects. Some additional information * required by the {@code BeanUtils} library is also stored here. * </p> * * @version $Id$ * @since 1.9.1 */
class BeanIntrospectionData {
An array with property descriptors for the managed bean class.
/** An array with property descriptors for the managed bean class. */
private final PropertyDescriptor[] descriptors;
A map for remembering the write method names for properties.
/** A map for remembering the write method names for properties. */
private final Map<String, String> writeMethodNames;
Creates a new instance of BeanIntrospectionData and initializes its completely.
Params:
  • descs – the array with the descriptors of the available properties
/** * Creates a new instance of {@code BeanIntrospectionData} and initializes its * completely. * * @param descs the array with the descriptors of the available properties */
public BeanIntrospectionData(final PropertyDescriptor[] descs) { this(descs, setUpWriteMethodNames(descs)); }
Creates a new instance of BeanIntrospectionData and allows setting the map with write method names. This constructor is mainly used for testing purposes.
Params:
  • descs – the array with the descriptors of the available properties
  • writeMethNames – the map with the names of write methods
/** * Creates a new instance of {@code BeanIntrospectionData} and allows setting the map * with write method names. This constructor is mainly used for testing purposes. * * @param descs the array with the descriptors of the available properties * @param writeMethNames the map with the names of write methods */
BeanIntrospectionData(final PropertyDescriptor[] descs, final Map<String, String> writeMethNames) { descriptors = descs; writeMethodNames = writeMethNames; }
Returns the array with property descriptors.
Returns:the property descriptors for the associated bean class
/** * Returns the array with property descriptors. * * @return the property descriptors for the associated bean class */
public PropertyDescriptor[] getDescriptors() { return descriptors; }
Returns the PropertyDescriptor for the property with the specified name. If this property is unknown, result is null.
Params:
  • name – the name of the property in question
Returns:the PropertyDescriptor for this property or null
/** * Returns the {@code PropertyDescriptor} for the property with the specified name. If * this property is unknown, result is <b>null</b>. * * @param name the name of the property in question * @return the {@code PropertyDescriptor} for this property or <b>null</b> */
public PropertyDescriptor getDescriptor(final String name) { for (final PropertyDescriptor pd : getDescriptors()) { if (name.equals(pd.getName())) { return pd; } } return null; }
Returns the write method for the property determined by the given PropertyDescriptor. This information is normally available in the descriptor object itself. However, at least by the ORACLE implementation, the method is stored as a SoftReference. If this reference has been freed by the GC, it may be the case that the method cannot be obtained again. Then, additional information stored in this object is necessary to obtain the method again.
Params:
  • beanCls – the class of the affected bean
  • desc – the PropertyDescriptor of the desired property
Returns:the write method for this property or null if there is none
/** * Returns the write method for the property determined by the given * {@code PropertyDescriptor}. This information is normally available in the * descriptor object itself. However, at least by the ORACLE implementation, the * method is stored as a {@code SoftReference}. If this reference has been freed by * the GC, it may be the case that the method cannot be obtained again. Then, * additional information stored in this object is necessary to obtain the method * again. * * @param beanCls the class of the affected bean * @param desc the {@code PropertyDescriptor} of the desired property * @return the write method for this property or <b>null</b> if there is none */
public Method getWriteMethod(final Class<?> beanCls, final PropertyDescriptor desc) { Method method = desc.getWriteMethod(); if (method == null) { final String methodName = writeMethodNames.get(desc.getName()); if (methodName != null) { method = MethodUtils.getAccessibleMethod(beanCls, methodName, desc.getPropertyType()); if (method != null) { try { desc.setWriteMethod(method); } catch (final IntrospectionException e) { // ignore, in this case the method is not cached } } } } return method; }
Initializes the map with the names of the write methods for the supported properties. The method names - if defined - need to be stored separately because they may get lost when the GC claims soft references used by the PropertyDescriptor objects.
Params:
  • descs – the array with the descriptors of the available properties
Returns:the map with the names of write methods for properties
/** * Initializes the map with the names of the write methods for the supported * properties. The method names - if defined - need to be stored separately because * they may get lost when the GC claims soft references used by the * {@code PropertyDescriptor} objects. * * @param descs the array with the descriptors of the available properties * @return the map with the names of write methods for properties */
private static Map<String, String> setUpWriteMethodNames(final PropertyDescriptor[] descs) { final Map<String, String> methods = new HashMap<String, String>(); for (final PropertyDescriptor pd : descs) { final Method method = pd.getWriteMethod(); if (method != null) { methods.put(pd.getName(), method.getName()); } } return methods; } }