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]

Reply via email to