You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Apache Wiki <wi...@apache.org> on 2005/10/04 04:02:42 UTC

[Struts Wiki] Update of "StrutsCatalogLazyList" by DerekClarkson

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
+  * {@link 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: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org