com.vaadin.data.util.BeanItem Maven / Gradle / Ivy
/*
* Vaadin Framework 7
*
* Copyright (C) 2000-2024 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See for the full
* license.
*/
package com.vaadin.data.util;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.vaadin.data.Property;
/**
* A wrapper class for adding the Item interface to any Java Bean.
*
* @author Vaadin Ltd.
* @since 3.0
*/
@SuppressWarnings("serial")
public class BeanItem extends PropertysetItem {
/**
* The bean which this Item is based on.
*/
private BT bean;
/**
*
* Creates a new instance of BeanItem
and adds all properties
* of a Java Bean to it. The properties are identified by their respective
* bean names.
*
*
*
* Note : This version only supports introspectable bean properties and
* their getter and setter methods. Stand-alone is
and
* are
methods are not supported.
*
*
* @param bean
* the Java Bean to copy properties from.
*
*/
public BeanItem(BT bean) {
this(bean, (Class) bean.getClass());
}
/**
*
* Creates a new instance of BeanItem
and adds all properties
* of a Java Bean to it. The properties are identified by their respective
* bean names.
*
*
*
* Note : This version only supports introspectable bean properties and
* their getter and setter methods. Stand-alone is
and
* are
methods are not supported.
*
*
* @since 7.4
*
* @param bean
* the Java Bean to copy properties from.
* @param beanClass
* class of the {@code bean}
*
*/
public BeanItem(BT bean, Class beanClass) {
this(bean, getPropertyDescriptors(beanClass));
}
/**
*
* Creates a new instance of BeanItem
using a pre-computed set
* of properties. The properties are identified by their respective bean
* names.
*
*
* @param bean
* the Java Bean to copy properties from.
* @param propertyDescriptors
* pre-computed property descriptors
*/
BeanItem(BT bean,
Map> propertyDescriptors) {
this.bean = bean;
for (VaadinPropertyDescriptor pd : propertyDescriptors.values()) {
addItemProperty(pd.getName(), pd.createProperty(bean));
}
}
/**
*
* Creates a new instance of BeanItem
and adds all listed
* properties of a Java Bean to it - in specified order. The properties are
* identified by their respective bean names.
*
*
*
* Note : This version only supports introspectable bean properties and
* their getter and setter methods. Stand-alone is
and
* are
methods are not supported.
*
*
* @param bean
* the Java Bean to copy properties from.
* @param propertyIds
* id of the property.
*/
public BeanItem(BT bean, Collection> propertyIds) {
this.bean = bean;
// Create bean information
LinkedHashMap> pds = getPropertyDescriptors(
(Class) bean.getClass());
// Add all the bean properties as MethodProperties to this Item
for (Object id : propertyIds) {
VaadinPropertyDescriptor pd = pds.get(id);
if (pd != null) {
addItemProperty(pd.getName(), pd.createProperty(bean));
}
}
}
/**
*
* Creates a new instance of BeanItem
and adds all listed
* properties of a Java Bean to it - in specified order. The properties are
* identified by their respective bean names.
*
*
*
* Note : This version only supports introspectable bean properties and
* their getter and setter methods. Stand-alone is
and
* are
methods are not supported.
*
*
* @param bean
* the Java Bean to copy properties from.
* @param propertyIds
* ids of the properties.
*/
public BeanItem(BT bean, String... propertyIds) {
this(bean, Arrays.asList(propertyIds));
}
/**
*
* Perform introspection on a Java Bean class to find its properties.
*
*
*
* Note : This version only supports introspectable bean properties and
* their getter and setter methods. Stand-alone is
and
* are
methods are not supported.
*
*
* @param beanClass
* the Java Bean class to get properties for.
* @return an ordered map from property names to property descriptors
*/
static LinkedHashMap> getPropertyDescriptors(
final Class beanClass) {
final LinkedHashMap> pdMap = new LinkedHashMap>();
// Try to introspect, if it fails, we just have an empty Item
try {
List propertyDescriptors = BeanUtil
.getBeanPropertyDescriptor(beanClass);
// Add all the bean properties as MethodProperties to this Item
// later entries on the list overwrite earlier ones
for (PropertyDescriptor pd : propertyDescriptors) {
final Method getMethod = pd.getReadMethod();
if ((getMethod != null)
&& getMethod.getDeclaringClass() != Object.class) {
VaadinPropertyDescriptor vaadinPropertyDescriptor = new MethodPropertyDescriptor(
pd.getName(), pd.getPropertyType(),
pd.getReadMethod(), pd.getWriteMethod());
pdMap.put(pd.getName(), vaadinPropertyDescriptor);
}
}
} catch (final java.beans.IntrospectionException ignored) {
}
return pdMap;
}
/**
* Expands nested bean properties by replacing a top-level property with
* some or all of its sub-properties. The expansion is not recursive.
*
* @param propertyId
* property id for the property whose sub-properties are to be
* expanded,
* @param subPropertyIds
* sub-properties to expand, all sub-properties are expanded if
* not specified
*/
public void expandProperty(String propertyId, String... subPropertyIds) {
Set subPropertySet = new HashSet(
Arrays.asList(subPropertyIds));
if (0 == subPropertyIds.length) {
// Enumerate all sub-properties
Class> propertyType = getItemProperty(propertyId).getType();
Map pds = getPropertyDescriptors(propertyType);
subPropertySet.addAll(pds.keySet());
}
for (String subproperty : subPropertySet) {
String qualifiedPropertyId = propertyId + "." + subproperty;
addNestedProperty(qualifiedPropertyId);
}
removeItemProperty(propertyId);
}
/**
* Adds a nested property to the item. The property must not exist in the
* item already and must of form "field1.field2" where field2 is a field in
* the object referenced to by field1. If an intermediate property returns
* null, the property will return a null value
*
* @param nestedPropertyId
* property id to add.
*/
public void addNestedProperty(String nestedPropertyId) {
addItemProperty(nestedPropertyId,
new NestedMethodProperty