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