struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jose Gonzalez Gomez <jgonza...@opentechnet.com>
Subject DynaActionForm and array types without size or initial
Date Mon, 03 Mar 2003 20:32:37 GMT

    Hello,

    I've been searching the list for this, but I haven't find any 
solution. Whenever you use an indexed property in a DynaActionForm or 
DynaValidatorActionForm you always must specify size or initial, as 
failing to do so will cause Struts to give a null value to the property, 
and this will cause a NPE when submitting a form with this bean.

    I think that one of the common scenarios for using an indexed 
property is when you have a dynamic form, so you don't know the size of 
the form in compile time. Think, for example, in a shopping cart where 
you want to edit quantities of products, or details of a purchase order 
where you want to select single details with checkboxes to remove them 
in a single step. The only solution I have found in this kind of 
scenarios is to create and prepopulate the bean, store it in session, 
and retrieve it after submitting the form. Anyway, this has the problem 
of resetting the values.

    Anybody of you has faced these problems?

    I've taken a look at the Struts code, and it seems it wouldn't be 
difficult to change this behaviour and provide "dynamic" lists that 
would back this indexed properties in DynaActionForms. Basically, the 
change should be done in the initial method of FormPropertyConfig. A 
lazy list from commons-collections (ListUtils) could be used only if the 
implementation would provide not only on-the-fly creation of objects 
when getting them, but also when setting them. I mean, if you, for 
example, set the object in position 5, and the list is empty, create 
default objects for positions 0-4 and add object in position 5. 
Currently the lazy list only provides this behaviour when getting 
objects. What do you think about this? Any committer that could comment 
on this?

    Another problem for this is to create default objects for java 
wrapper classes of primitive types, as they don't provide default 
construtctors, but I guess this could be controlled and create objects 
with default values (0 for numbers, false for booleans...). This makes 
me think of the posibility of adding a new attribute to the 
form-property tag, that specifies the initial value for newly created 
objects inside the list, instead of specifying the initial value of the 
whole list. What do you think?

    I include a possible implementation of inital using ListUtils.lazyList:

    public Object initial() {

        Object initialValue = null;
        try {
            final Class clazz = getTypeClass();
            if (clazz.isArray()) {
                if (initial != null) {
                    initialValue =
                        ConvertUtils.convert(initial, clazz);
                } else {
                    if( size > 0 ) {
                        initialValue =
                            Array.newInstance(clazz.getComponentType(), 
size);
                        for (int i = 0; i < size; i++) {
                            try {
                                Array.set(initialValue, i,
                                          
clazz.getComponentType().newInstance());
                            } catch (Throwable t) {
                                ; // Probably does not have a zero-args 
constructor
                            }
                        }
                    } else {
                        initialValue =
                            ListUtils.lazyList( new ArrayList( ), new 
Factory() {
                                public Object create() {
                                    try {
                                        return 
clazz.getComponentType().newInstance();
                                    } catch (Throwable t) {
                                        return null; // Probably does 
not have a zero-args constructor
                                    }
                                }
                            } );
                    }
                }
            } else {
                if (initial != null) {
                    initialValue = ConvertUtils.convert(initial, clazz);
                } else {
                    initialValue = clazz.newInstance();
                }
            }
        } catch (Throwable t) {
            initialValue = null;
        }
        return (initialValue);

    }

    Regards
    Jose


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-dev-help@jakarta.apache.org


Mime
View raw message