Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification.
The following page has been changed by DerekClarkson: http://wiki.apache.org/struts/StrutsCatalogLazyList ------------------------------------------------------------------------------ Derek Clarkson + === Extending the struts DynaActionForm === + I came up with this code after looking around and not really being satified with any of the solutions I found. They either required a lot of fiddling and setup in the application, or involved install all sorts of packages I didn't really want to use. Basically I don't like making things any more complex than they should be. So I came up with this class which extends the struts DynaActionForm to effective lazy load lists and arrays without requiring any additional software or setup over the standard DynaActionForm. + + {{{ + package com.dhc.form; + + import org.apache.struts.action.DynaActionForm; + + import java.lang.reflect.Array; + import java.util.List; + + /** + * This class extends + * [EMAIL PROTECTED] org.apache.struts.action.DynaActionForm DynaActionForm} so that we can + * fix the issues where array references in the properties are not created and + * cause index exceptions to be thrown. The intent is to re-code the set method + * so that when an index value is being set, the arrays are extended as + * necessary by an automatic process. This should remove the necessity for using + * one of a number of messy work-arounds being used by the struts community. + * <p> + * <b>NOTE</b> after submitting this for comment on java ranch I found out about a + * similar thing using the Bean utils lazy forms. However when I tried to implement + * it, I ran into all sorts of problems with implementing. Most notibly they are + * heavily linked to the use of the Validator which menas you must register all forms + * with it before you can use the lazy forms. It took me some time to work this out + * because the error messages that are generated are very vague about what the issue is + * which makes it difficult to sort out. + * <p> + * I also looked at using the commons collection LazyList to drive it. but the issue + * with that is that it requires the class to provide a factory for generating + * objects to be stored. This is ok when you know what you are storing but the idea + * behind a dynaactionform is that you do not. + * <p> + * To cut a long story short this code is smaller, requires no implementation, xml files + * supporting it or other libraries. + * + * + * @author Derek Clarkson + */ + public class LazyDynaActionForm extends DynaActionForm { + + // @Override + public void set(String name, int index, Object value) { + + // get the array container from the hashmap of properties. This should + // return an array object or a list. + Object prop = this.dynaValues.get(name); + Class arrayClass = prop.getClass(); + + // error trap. + if (prop == null) { + throw new NullPointerException("No indexed value for '" + name + "[" + index + "]'"); + } + + if (arrayClass.isArray()) { + + // First check that the array is big enough. If not then we need to + // expand it and store the expanded one. + if (Array.getLength(prop) < index + 1) { + Object newArray = Array.newInstance(arrayClass.getComponentType(), index + 1); + System.arraycopy(prop, 0, newArray, 0, Array.getLength(prop)); + this.dynaValues.put(name, newArray); + prop = newArray; + } + + // Now store the value. + Array.set(prop, index, value); + + } else if (prop instanceof List) { + + // Quick local ref for ease of coding. + List list = (List) prop; + + // Now check the length and expand as necessary. + if (list.size() < index + 1) { + + // I could not see any way of doing this other than this. Basically + // because my criteria was + // that I did not want to replace the list, only expand it because + // then I would not have to deal + // with issues of getting the correct type, etc. Alternatives welcome. + for (int i = list.size(); i <= index; i++) { + list.add(null); + } + } + + // Store the new value. + list.set(index, value); + + } else { + throw new IllegalArgumentException("Non-indexed property for '" + name + "[" + index + "]'"); + } + + } + } + + }}} + + Enjoy, + Derek Clarkson + --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
