Re: Not happy with approaches.. looking for better/other suggestions
Just a silly question. Where did ListUtils come from?? I can't find this in my JDK1.4.2. Thanks - Original Message - From: Hubert Rabago [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Sent: Friday, September 03, 2004 7:40 AM Subject: Re: Not happy with approaches.. looking for better/other suggestions Have you tried using ListUtils.lazyList() for this? I just tried it on a sample app and it works in cases like this. - Hubert On Thu, 02 Sep 2004 14:27:32 -0400, Rick Reumann [EMAIL PROTECTED] wrote: One of the most frustrating things I run into when developing Struts applications is the problem of when you want to use a request scoped ActionForm but you need to populate a collection that is one of your ActionForm properties. The problem is the classic index out of bounds exception if you do not have your collection populated with enough objects. For example imagine the case where you might want to edit a bunch of Access definitions on one form. So in an ActionForm property you have: Collection accessDefinitions; In your Action before you get to the form you populate your form: ((AccessForm)form).setAccessDefinitions( aCollectionOfDefs ); Your JSP then displays the access definition properties for the user to edit: (condensed and table formatting removed:) c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status html:text property=accessDefinitions[${status.index}].name/ html:text property=accessDefinitions[${status.index}].description/ /c:forEach Now the problem will be when you submit this form. If this form was given request scope in the action mapping, you'll end up with errors since BeanUtils can not populate the Collection. You need to have the correct size in place for 'accessDefinitions' to allow for population. There are several solutions that have been proposed by searching the list archives. The easiest alternative is of course to just put your form in Session scope, but that is such a waste in my opinion. Another approach would be something like: In reset() of ActionForm: public void reset(ActionMapping actionMapping, HttpServletRequest request) { if ( request.getParameter(accessDefinitionsSize) != null ) { int accessDefinitionsSize = new Integer(request.getParameter(accessDefinitionsSize)).intValue(); accessDefinitions = new ArrayList(accessDefinitionsSize); for (int i=0;iaccessDefinitionsSize;i++) { accessDefinitions.add(new AccessDefinitionVO()); } } } Then in your JSP (code snipped just showing releveant portion): c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status c:set var=accessDefinitionsSize value=${status.count}/ /c:forEach input type=hidden name=accessDefinitionsSize value=${accessDefinitionsSize}/ The above works 'ok' but it's so much extra code. I've thought of just adding the accessDefinitionsSize attribute to the Session in the Action that is called right be the form is set up. Then the reset method can pull it right from there. An int in the session won't be too much overhead. But I'm not sure if I like that approach that much either (although I'm leaning towards just doing it that way). Of course I don't like the approaches that call a business class from the reset to get the size. Any suggestions welcome. -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Not happy with approaches.. looking for better/other suggestions
Dude all you have to do is do something as simple as entering ListUtils in Google and you'll find out. -Yves- On Mon, 13 Sep 2004 17:04:18 +1200, struts Dude [EMAIL PROTECTED] wrote: Just a silly question. Where did ListUtils come from?? I can't find this in my JDK1.4.2. Thanks - Original Message - From: Hubert Rabago [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Sent: Friday, September 03, 2004 7:40 AM Subject: Re: Not happy with approaches.. looking for better/other suggestions Have you tried using ListUtils.lazyList() for this? I just tried it on a sample app and it works in cases like this. - Hubert On Thu, 02 Sep 2004 14:27:32 -0400, Rick Reumann [EMAIL PROTECTED] wrote: One of the most frustrating things I run into when developing Struts applications is the problem of when you want to use a request scoped ActionForm but you need to populate a collection that is one of your ActionForm properties. The problem is the classic index out of bounds exception if you do not have your collection populated with enough objects. For example imagine the case where you might want to edit a bunch of Access definitions on one form. So in an ActionForm property you have: Collection accessDefinitions; In your Action before you get to the form you populate your form: ((AccessForm)form).setAccessDefinitions( aCollectionOfDefs ); Your JSP then displays the access definition properties for the user to edit: (condensed and table formatting removed:) c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status html:text property=accessDefinitions[${status.index}].name/ html:text property=accessDefinitions[${status.index}].description/ /c:forEach Now the problem will be when you submit this form. If this form was given request scope in the action mapping, you'll end up with errors since BeanUtils can not populate the Collection. You need to have the correct size in place for 'accessDefinitions' to allow for population. There are several solutions that have been proposed by searching the list archives. The easiest alternative is of course to just put your form in Session scope, but that is such a waste in my opinion. Another approach would be something like: In reset() of ActionForm: public void reset(ActionMapping actionMapping, HttpServletRequest request) { if ( request.getParameter(accessDefinitionsSize) != null ) { int accessDefinitionsSize = new Integer(request.getParameter(accessDefinitionsSize)).intValue(); accessDefinitions = new ArrayList(accessDefinitionsSize); for (int i=0;iaccessDefinitionsSize;i++) { accessDefinitions.add(new AccessDefinitionVO()); } } } Then in your JSP (code snipped just showing releveant portion): c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status c:set var=accessDefinitionsSize value=${status.count}/ /c:forEach input type=hidden name=accessDefinitionsSize value=${accessDefinitionsSize}/ The above works 'ok' but it's so much extra code. I've thought of just adding the accessDefinitionsSize attribute to the Session in the Action that is called right be the form is set up. Then the reset method can pull it right from there. An int in the session won't be too much overhead. But I'm not sure if I like that approach that much either (although I'm leaning towards just doing it that way). Of course I don't like the approaches that call a business class from the reset to get the size. Any suggestions welcome. -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- For me to poop on! http://www.formetopoopon.com http://www.nbc.com/nbc/Late_Night_with_Conan_O'Brien/video/triumph.shtml - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Not happy with approaches.. looking for better/other suggestions
hi Rick, have you tried defining the following in your ActionForm? (assuming your collection has MyFooBar objects): public MyFooBar getAccessDefinitions(int i) { if(null == accessDefinitions) accessDefinitions = new ArrayList(); while(i = accessDefinitions.size()) ((ArrayList)accessDefinitions).add(new MyFooBar()) return (MyFooBar) ((ArrayList)accessDefinitions).get(i); } can this help you to populate form data onto your ActionForm collection? woodchuck --- Rick Reumann [EMAIL PROTECTED] wrote: One of the most frustrating things I run into when developing Struts applications is the problem of when you want to use a request scoped ActionForm but you need to populate a collection that is one of your ActionForm properties. The problem is the classic index out of bounds exception if you do not have your collection populated with enough objects. For example imagine the case where you might want to edit a bunch of Access definitions on one form. So in an ActionForm property you have: Collection accessDefinitions; In your Action before you get to the form you populate your form: ((AccessForm)form).setAccessDefinitions( aCollectionOfDefs ); Your JSP then displays the access definition properties for the user to edit: (condensed and table formatting removed:) c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status html:text property=accessDefinitions[${status.index}].name/ html:text property=accessDefinitions[${status.index}].description/ /c:forEach Now the problem will be when you submit this form. If this form was given request scope in the action mapping, you'll end up with errors since BeanUtils can not populate the Collection. You need to have the correct size in place for 'accessDefinitions' to allow for population. There are several solutions that have been proposed by searching the list archives. The easiest alternative is of course to just put your form in Session scope, but that is such a waste in my opinion. Another approach would be something like: In reset() of ActionForm: public void reset(ActionMapping actionMapping, HttpServletRequest request) { if ( request.getParameter(accessDefinitionsSize) != null ) { int accessDefinitionsSize = new Integer(request.getParameter(accessDefinitionsSize)).intValue(); accessDefinitions = new ArrayList(accessDefinitionsSize); for (int i=0;iaccessDefinitionsSize;i++) { accessDefinitions.add(new AccessDefinitionVO()); } } } Then in your JSP (code snipped just showing releveant portion): c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status c:set var=accessDefinitionsSize value=${status.count}/ /c:forEach input type=hidden name=accessDefinitionsSize value=${accessDefinitionsSize}/ The above works 'ok' but it's so much extra code. I've thought of just adding the accessDefinitionsSize attribute to the Session in the Action that is called right be the form is set up. Then the reset method can pull it right from there. An int in the session won't be too much overhead. But I'm not sure if I like that approach that much either (although I'm leaning towards just doing it that way). Of course I don't like the approaches that call a business class from the reset to get the size. Any suggestions welcome. -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] ___ Do you Yahoo!? Win 1 of 4,000 free domain names from Yahoo! Enter now. http://promotions.yahoo.com/goldrush - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Not happy with approaches.. looking for better/other suggestions
Have you tried using ListUtils.lazyList() for this? I just tried it on a sample app and it works in cases like this. - Hubert On Thu, 02 Sep 2004 14:27:32 -0400, Rick Reumann [EMAIL PROTECTED] wrote: One of the most frustrating things I run into when developing Struts applications is the problem of when you want to use a request scoped ActionForm but you need to populate a collection that is one of your ActionForm properties. The problem is the classic index out of bounds exception if you do not have your collection populated with enough objects. For example imagine the case where you might want to edit a bunch of Access definitions on one form. So in an ActionForm property you have: Collection accessDefinitions; In your Action before you get to the form you populate your form: ((AccessForm)form).setAccessDefinitions( aCollectionOfDefs ); Your JSP then displays the access definition properties for the user to edit: (condensed and table formatting removed:) c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status html:text property=accessDefinitions[${status.index}].name/ html:text property=accessDefinitions[${status.index}].description/ /c:forEach Now the problem will be when you submit this form. If this form was given request scope in the action mapping, you'll end up with errors since BeanUtils can not populate the Collection. You need to have the correct size in place for 'accessDefinitions' to allow for population. There are several solutions that have been proposed by searching the list archives. The easiest alternative is of course to just put your form in Session scope, but that is such a waste in my opinion. Another approach would be something like: In reset() of ActionForm: public void reset(ActionMapping actionMapping, HttpServletRequest request) { if ( request.getParameter(accessDefinitionsSize) != null ) { int accessDefinitionsSize = new Integer(request.getParameter(accessDefinitionsSize)).intValue(); accessDefinitions = new ArrayList(accessDefinitionsSize); for (int i=0;iaccessDefinitionsSize;i++) { accessDefinitions.add(new AccessDefinitionVO()); } } } Then in your JSP (code snipped just showing releveant portion): c:forEach items=${accessForm.accessDefinitions} var=access varStatus=status c:set var=accessDefinitionsSize value=${status.count}/ /c:forEach input type=hidden name=accessDefinitionsSize value=${accessDefinitionsSize}/ The above works 'ok' but it's so much extra code. I've thought of just adding the accessDefinitionsSize attribute to the Session in the Action that is called right be the form is set up. Then the reset method can pull it right from there. An int in the session won't be too much overhead. But I'm not sure if I like that approach that much either (although I'm leaning towards just doing it that way). Of course I don't like the approaches that call a business class from the reset to get the size. Any suggestions welcome. -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Not happy with approaches.. looking for better/other suggestions
Hubert Rabago wrote: Have you tried using ListUtils.lazyList() for this? I just tried it on a sample app and it works in cases like this. No I haven't tried that. Even with that, how is the lazy load going to know the size to load without calling a business class behind the scenes? (which seems really goofy just to get a size). -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Not happy with approaches.. looking for better/other suggestions
It doesn't. What happens is, when Struts tries to access the nth bean to populate it, the lazyList creates a bean and puts it at the nth index. Here's what I put in my ActionForm: public class CollForm extends ActionForm { Collection accessDefinitions; public Collection getAccessDefinitions() { return accessDefinitions; } public void setAccessDefinitions(Collection accessDefinitions) { this.accessDefinitions = accessDefinitions; } public void reset(ActionMapping mapping, HttpServletRequest request) { super.reset(mapping, request); accessDefinitions = ListUtils.lazyList(new java.util.ArrayList(), new Factory() { public Object create() { return new AccessDefinition(); } }); } public static class AccessDefinition { String name; String description; public AccessDefinition() { } public AccessDefinition(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } } = Here's what I have in my action to prepopulate it: public ActionForward execute(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { CollForm form = new CollForm(); form.reset(mapping, request); Collection accessDefinitions = form.getAccessDefinitions(); accessDefinitions.add(new CollForm.AccessDefinition(http,internet)); accessDefinitions.add(new CollForm.AccessDefinition(jms,messaging)); form.setAccessDefinitions(accessDefinitions); request.setAttribute(collForm, form); return mapping.findForward(jsp); } = If you use an actual factory class instead of the anonymous one I used in CollForm.reset(), you won't have to call reset() in your Action, just call ListUtils.lazyList() directly. hth, Hubert On Thu, 02 Sep 2004 15:52:20 -0400, Rick Reumann [EMAIL PROTECTED] wrote: Hubert Rabago wrote: Have you tried using ListUtils.lazyList() for this? I just tried it on a sample app and it works in cases like this. No I haven't tried that. Even with that, how is the lazy load going to know the size to load without calling a business class behind the scenes? (which seems really goofy just to get a size). -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Not happy with approaches.. looking for better/other suggestions
Hubert Rabago wrote: public void reset(ActionMapping mapping, HttpServletRequest request) { super.reset(mapping, request); accessDefinitions = ListUtils.lazyList(new java.util.ArrayList(), new Factory() { public Object create() { return new AccessDefinition(); } }); Ok that is just way too cool:) This is perfect. Now I have to look at the API to figure out what's going on. Way awesome. -- Rick - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]