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

com.vaadin.v7.data.fieldgroup.BeanFieldGroup Maven / Gradle / Ivy

There is a newer version: 8.27.3
Show newest version
/*
 * 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.v7.data.fieldgroup;

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

import com.vaadin.data.BeanValidationBinder;
import com.vaadin.data.Binder;
import com.vaadin.data.util.BeanUtil;
import com.vaadin.v7.data.Item;
import com.vaadin.v7.data.util.BeanItem;
import com.vaadin.v7.data.validator.BeanValidator;
import com.vaadin.v7.ui.Field;

/**
 *
 * @deprecated As of 8.0, replaced by {@link Binder} and
 *             {@link BeanValidationBinder}
 */
@Deprecated
public class BeanFieldGroup extends FieldGroup {

    private final Class beanType;

    private static Boolean beanValidationImplementationAvailable = null;
    private final Map, BeanValidator> defaultValidators;

    public BeanFieldGroup(Class beanType) {
        this.beanType = beanType;
        this.defaultValidators = new HashMap, BeanValidator>();
    }

    @Override
    protected Class getPropertyType(Object propertyId) {
        if (getItemDataSource() != null) {
            return super.getPropertyType(propertyId);
        } else {
            // Data source not set so we need to figure out the type manually
            /*
             * toString should never really be needed as propertyId should be of
             * form "fieldName" or "fieldName.subField[.subField2]" but the
             * method declaration comes from parent.
             */
            try {
                Class type = BeanUtil.getPropertyType(beanType,
                        propertyId.toString());
                if (type == null) {
                    throw new BindException(
                            "Cannot determine type of propertyId '" + propertyId
                                    + "'. The propertyId was not found in "
                                    + beanType.getName());
                }
                return type;
            } catch (IntrospectionException e) {
                throw new BindException("Cannot determine type of propertyId '"
                        + propertyId + "'. Unable to introspect " + beanType,
                        e);
            }
        }
    }

    @Override
    protected Object findPropertyId(java.lang.reflect.Field memberField) {
        String fieldName = memberField.getName();
        Item dataSource = getItemDataSource();
        if (dataSource != null
                && dataSource.getItemProperty(fieldName) != null) {
            return fieldName;
        } else {
            String minifiedFieldName = minifyFieldName(fieldName);
            try {
                return getFieldName(beanType, minifiedFieldName);
            } catch (SecurityException e) {
            } catch (NoSuchFieldException e) {
            }
        }
        return null;
    }

    private static String getFieldName(Class cls, String propertyId)
            throws SecurityException, NoSuchFieldException {
        for (java.lang.reflect.Field field1 : cls.getDeclaredFields()) {
            if (propertyId.equals(minifyFieldName(field1.getName()))) {
                return field1.getName();
            }
        }
        // Try super classes until we reach Object
        Class superClass = cls.getSuperclass();
        if (superClass != null && superClass != Object.class) {
            return getFieldName(superClass, propertyId);
        } else {
            throw new NoSuchFieldException();
        }
    }

    /**
     * Helper method for setting the data source directly using a bean. This
     * method wraps the bean in a {@link BeanItem} and calls
     * {@link #setItemDataSource(Item)}.
     * 

* For null values, a null item is passed to * {@link #setItemDataSource(Item)} to be properly clear fields. * * @param bean * The bean to use as data source. */ public void setItemDataSource(T bean) { if (bean == null) { setItemDataSource((Item) null); } else { setItemDataSource(new BeanItem(bean, beanType)); } } @Override public void setItemDataSource(Item item) { if (item == null || (item instanceof BeanItem)) { super.setItemDataSource(item); } else { throw new RuntimeException(getClass().getSimpleName() + " only supports BeanItems as item data source"); } } @Override public BeanItem getItemDataSource() { return (BeanItem) super.getItemDataSource(); } private void ensureNestedPropertyAdded(Object propertyId) { if (getItemDataSource() != null) { // The data source is set so the property must be found in the item. // If it is not we try to add it. try { getItemProperty(propertyId); } catch (BindException e) { // Not found, try to add a nested property; // BeanItem property ids are always strings so this is safe getItemDataSource().addNestedProperty((String) propertyId); } } } @Override public void bind(Field field, Object propertyId) { ensureNestedPropertyAdded(propertyId); super.bind(field, propertyId); } @Override public T buildAndBind(String caption, Object propertyId, Class fieldType) throws BindException { ensureNestedPropertyAdded(propertyId); return super.buildAndBind(caption, propertyId, fieldType); } @Override public void unbind(Field field) throws BindException { super.unbind(field); BeanValidator removed = defaultValidators.remove(field); if (removed != null) { field.removeValidator(removed); } } @Override protected void configureField(Field field) { super.configureField(field); // Add Bean validators if there are annotations if (isBeanValidationImplementationAvailable() && !defaultValidators.containsKey(field)) { BeanValidator validator = new BeanValidator(beanType, getPropertyId(field).toString()); field.addValidator(validator); if (field.getLocale() != null) { validator.setLocale(field.getLocale()); } defaultValidators.put(field, validator); } } /** * Checks whether a bean validation implementation (e.g. Hibernate Validator * or Apache Bean Validation) is available. * * TODO move this method to some more generic location * * @return true if a JSR-303 bean validation implementation is available */ protected static boolean isBeanValidationImplementationAvailable() { if (beanValidationImplementationAvailable != null) { return beanValidationImplementationAvailable; } try { Class validationClass = Class .forName("javax.validation.Validation"); Method buildFactoryMethod = validationClass .getMethod("buildDefaultValidatorFactory"); Object factory = buildFactoryMethod.invoke(null); beanValidationImplementationAvailable = (factory != null); } catch (Exception e) { // no bean validation implementation available beanValidationImplementationAvailable = false; } return beanValidationImplementationAvailable; } /** * Convenience method to bind Fields from a given "field container" to a * given bean with buffering disabled. *

* The returned {@link BeanFieldGroup} can be used for further * configuration. * * @see #bindFieldsBuffered(Object, Object) * @see #bindMemberFields(Object) * @since 7.2 * @param bean * the bean to be bound * @param objectWithMemberFields * the class that contains {@link Field}s for bean properties * @return the bean field group used to make binding */ public static BeanFieldGroup bindFieldsUnbuffered(T bean, Object objectWithMemberFields) { return createAndBindFields(bean, objectWithMemberFields, false); } /** * Convenience method to bind Fields from a given "field container" to a * given bean with buffering enabled. *

* The returned {@link BeanFieldGroup} can be used for further * configuration. * * @see #bindFieldsUnbuffered(Object, Object) * @see #bindMemberFields(Object) * @since 7.2 * @param bean * the bean to be bound * @param objectWithMemberFields * the class that contains {@link Field}s for bean properties * @return the bean field group used to make binding */ public static BeanFieldGroup bindFieldsBuffered(T bean, Object objectWithMemberFields) { return createAndBindFields(bean, objectWithMemberFields, true); } private static BeanFieldGroup createAndBindFields(T bean, Object objectWithMemberFields, boolean buffered) { @SuppressWarnings("unchecked") BeanFieldGroup beanFieldGroup = new BeanFieldGroup( (Class) bean.getClass()); beanFieldGroup.setItemDataSource(bean); beanFieldGroup.setBuffered(buffered); beanFieldGroup.bindMemberFields(objectWithMemberFields); return beanFieldGroup; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy