org.andromda.presentation.gui.FormPopulator.java Source code

Java tutorial

Introduction

Here is the source code for org.andromda.presentation.gui.FormPopulator.java

Source

// license-header java merge-point
// Generated by andromda-jsf cartridge (utils\FormPopulator.java.vsl) DO NOT EDIT!
package org.andromda.presentation.gui;

import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * Provides utilities for population of forms
 * when using JSF.
 *
 * @author Chad Brandon
 */
public class FormPopulator implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * Copies the properties from the <code>fromForm</code> to the <code>toForm</code>.  Only passes not-null values to the toForm.
     *
     * @param fromForm the form from which we're populating
     * @param toForm the form to which we're populating
     */
    public static final void populateForm(final Object fromForm, final Object toForm) {
        populateForm(fromForm, toForm, false);
    }

    /**
     * Copies the properties from the <code>fromForm</code> to the <code>toForm</code>.  Only passes not-null values to the toForm.
     *
     * @param fromForm the form from which we're populating
     * @param toForm the form to which we're populating
     * @param override whether or not properties that have already been copied, should be overridden.
     */
    @SuppressWarnings("unchecked") // apache commons-beanutils PropertyUtils has no generics
    public static final void populateForm(final Object fromForm, final Object toForm, boolean override) {
        if (fromForm != null && toForm != null) {
            try {
                final Map<String, Object> parameters = PropertyUtils.describe(fromForm);
                for (final Iterator<String> iterator = parameters.keySet().iterator(); iterator.hasNext();) {
                    final String name = iterator.next();
                    if (PropertyUtils.isWriteable(toForm, name)) {
                        // - the property name used for checking whether or not the property value has been set
                        final String isSetPropertyName = name + "Set";
                        Boolean isToFormPropertySet = null;
                        Boolean isFromFormPropertySet = null;
                        // - only if override isn't true do we care whether or not the to property has been populated
                        if (!override) {
                            if (PropertyUtils.isReadable(toForm, isSetPropertyName)) {
                                isToFormPropertySet = (Boolean) PropertyUtils.getProperty(toForm,
                                        isSetPropertyName);
                            }
                        }
                        // - only if override is set to true, we check to see if the from form property has been set
                        if (override) {
                            if (PropertyUtils.isReadable(fromForm, isSetPropertyName)) {
                                isFromFormPropertySet = (Boolean) PropertyUtils.getProperty(fromForm,
                                        isSetPropertyName);
                            }
                        }
                        if (!override || (override && isFromFormPropertySet != null
                                && isFromFormPropertySet.booleanValue())) {
                            if (override || (isToFormPropertySet == null || !isToFormPropertySet.booleanValue())) {
                                final PropertyDescriptor toDescriptor = PropertyUtils.getPropertyDescriptor(toForm,
                                        name);
                                if (toDescriptor != null) {
                                    Object fromValue = parameters.get(name);
                                    // - only populate if not null
                                    if (fromValue != null) {
                                        final PropertyDescriptor fromDescriptor = PropertyUtils
                                                .getPropertyDescriptor(fromForm, name);
                                        // - only attempt to set if the types match
                                        if (fromDescriptor.getPropertyType() == toDescriptor.getPropertyType()) {
                                            PropertyUtils.setProperty(toForm, name, fromValue);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (final Throwable throwable) {
                throw new RuntimeException(throwable);
            }
        }
    }

    /**
     * Populates the form from the attributes contained in the request object.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param override whether or not to override properties already set on the given form.
     * @param assignableTypesOnly whether or not copying should be attempted only if the property types are assignable.
     */
    public static final void populateFormFromRequestAttributes(final Object form,
            final Map<String, DateFormat> formatters, boolean override, boolean assignableTypesOnly) {
        final FacesContext context = FacesContext.getCurrentInstance();
        final String[] names = JsfUtils.getAttributeNames(context.getExternalContext().getRequest());
        final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
        if (names != null) {
            for (final String name : names) {
                attributes.put(name, JsfUtils.getAttribute(context.getExternalContext().getRequest(), name));
            }
        }
        populateFormFromPropertyMap(form, formatters, attributes, null, override, assignableTypesOnly);
    }

    /**
     * Populates the form from the attributes contained in the request object.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param override whether or not to override properties already set on the given form.
     */
    public static final void populateFormFromRequestAttributes(final Object form,
            final Map<String, DateFormat> formatters, boolean override) {
        populateFormFromRequestAttributes(form, formatters, override, false);
    }

    /**
     * Populates the form from the given map of properties. If a matching property is null or an empty
     * string, then null is placed on the form.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param properties the properties to populate from.
     * @param override whether or not to override properties already set on the given form.
     */
    public static final void populateFormFromPropertyMap(final Object form,
            final Map<String, DateFormat> formatters, final Map<String, ?> properties, boolean override) {
        populateFormFromPropertyMap(form, formatters, properties, null, override, false);
    }

    /**
     * Populates the form from the given map of properties. If a matching property is null or an empty
     * string, then null is placed on the form.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param properties the properties to populate from.
     */
    public static final void populateFormFromPropertyMap(final Object form,
            final Map<String, DateFormat> formatters, final Map<String, ?> properties) {
        populateFormFromPropertyMap(form, formatters, properties, null, true, false);
    }

    /**
     * Populates the form from the given map of properties and populates only if the types
     * the properties are assignable. If a matching property is null or an empty
     * string, then null is placed on the form.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param properties the properties to populate from.
     */
    public static final void populateFormFromPropertyMapAssignableTypesOnly(final Object form,
            final Map<String, DateFormat> formatters, final Map<String, ?> properties) {
        populateFormFromPropertyMap(form, formatters, properties, null, true, true);
    }

    /**
     * Populates the form from the given map of properties. If a matching property is null or an empty
     * string, then null is placed on the form.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param properties the properties to populate from.
     * @param ignoreProperties names of any properties to ignore when it comes to populating on the form.
     */
    public static final void populateFormFromPropertyMap(final Object form,
            final Map<String, DateFormat> formatters, final Map<String, ?> properties,
            final String[] ignoreProperties) {
        populateFormFromPropertyMap(form, formatters, properties, ignoreProperties, true, false);
    }

    /**
     * Populates the form from the given map of properties. If a matching property is null or an empty
     * string, then null is placed on the form.
     *
     * @param form the form to populate.
     * @param formatters any date or time formatters.
     * @param properties the properties to populate from.
     * @param ignoreProperties names of any properties to ignore when it comes to populating on the form.
     * @param override whether or not to override properties already set on the given form.
     * @param assignableTypesOnly whether or not copying should be attempted only if the property types are assignable.
     */
    @SuppressWarnings("unchecked") // apache commons-beanutils PropertyUtils has no generics
    public static final void populateFormFromPropertyMap(final Object form,
            final Map<String, DateFormat> formatters, final Map<String, ?> properties,
            final String[] ignoreProperties, boolean override, boolean assignableTypesOnly) {
        if (properties != null) {
            try {
                final Collection<String> ignoredProperties = ignoreProperties != null
                        ? Arrays.asList(ignoreProperties)
                        : new ArrayList<String>();
                final Map<String, Object> formProperties = PropertyUtils.describe(form);
                for (final Iterator<String> iterator = formProperties.keySet().iterator(); iterator.hasNext();) {
                    final String name = iterator.next();
                    if (PropertyUtils.isWriteable(form, name) && !ignoredProperties.contains(name)) {
                        final PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptor(form, name);
                        if (descriptor != null) {
                            boolean populateProperty = true;
                            if (!override) {
                                final String isSetPropertyName = name + "Set";
                                if (PropertyUtils.isReadable(form, isSetPropertyName)) {
                                    final Boolean isPropertySet = (Boolean) PropertyUtils.getProperty(form,
                                            isSetPropertyName);
                                    if (isPropertySet.booleanValue()) {
                                        populateProperty = false;
                                    }
                                }
                            }
                            if (populateProperty) {
                                final Object property = properties.get(name);

                                // - only convert if the string is not empty
                                if (property != null) {
                                    Object value = null;
                                    if (property instanceof String) {
                                        final String propertyAsString = (String) property;
                                        if (propertyAsString.trim().length() > 0) {
                                            DateFormat formatter = formatters != null ? formatters.get(name) : null;
                                            // - if the formatter is available we use that, otherwise we attempt to convert
                                            if (formatter != null) {
                                                try {
                                                    value = formatter.parse(propertyAsString);
                                                } catch (ParseException parseException) {
                                                    // - try the default formatter (handles the default java.util.Date.toString() format)
                                                    formatter = formatters != null ? formatters.get(null) : null;
                                                    value = formatter.parse(propertyAsString);
                                                }
                                            } else {
                                                value = ConvertUtils.convert(propertyAsString,
                                                        descriptor.getPropertyType());
                                            }
                                        }
                                        // - don't attempt to set null on primitive fields
                                        if (value != null || !descriptor.getPropertyType().isPrimitive()) {
                                            PropertyUtils.setProperty(form, name, value);
                                        }
                                    } else {
                                        value = property;
                                        try {
                                            if (!assignableTypesOnly || descriptor.getPropertyType()
                                                    .isAssignableFrom(value.getClass())) {
                                                PropertyUtils.setProperty(form, name, value);
                                            }
                                        } catch (Exception exception) {
                                            final String valueTypeName = value.getClass().getName();
                                            final String propertyTypeName = descriptor.getPropertyType().getName();
                                            final StringBuilder message = new StringBuilder(
                                                    "Can not set form property '" + name + "' of type: "
                                                            + propertyTypeName + " with value: " + value);
                                            if (!descriptor.getPropertyType().isAssignableFrom(value.getClass())) {
                                                message.append("; " + valueTypeName + " is not assignable to "
                                                        + propertyTypeName);
                                            }
                                            throw new IllegalArgumentException(
                                                    message + ": " + exception.toString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (final Throwable throwable) {
                throw new RuntimeException(throwable);
            }
        }
    }
}