Re: ERXPatcher / WOBrowser / NSArray.addAll()
Re: ERXPatcher / WOBrowser / NSArray.addAll()
- Subject: Re: ERXPatcher / WOBrowser / NSArray.addAll()
- From: David Avendasora <email@hidden>
- Date: Fri, 27 Jan 2012 17:13:55 +0800
Hmm…
The problem is that I'm getting the exception in the takeValues phase, so changing it from updating the binding from invokeAction to appendToResponce has no impact as they both happen after the error is already being thrown.
This is really seeming like a bug in WOInputList#listClassInContext(WOContext) in that it returns an NSArray by default if the binding is null or otherwise not an instanceof NSArray or List.
I believe it should return an NSMutableArray instead.
Dave
On Jan 26, 2012, at 7:00 AM, David Avendasora wrote:
> Hi Michael,
>
> Yes, you are exactly right, except that we are setting the contents of the list binding (by assigning a new value to the ivar it's bound to) in invokeAction.
>
> public MyComponent showChoicesForSelection(){
> if (selectedCategory() != null){
> assignedChoices = selectedCategory().relatedChoices();
> }
> return thisPage();
> }
>
> selectedCategory() returns the value of the selections binding from a different WOBrowser component, and relatedChoices() is simply a toMany relationship.
>
> While initializing the ivar to NSArray.emptyArray() avoids the exception being thrown, I'm seeing that it is still broken code in the sense that we are changing the contents of the list binding at an unexpected time.
>
> Dave
>
> On Jan 25, 2012, at 11:07 PM, Michael Hast wrote:
>
>> Hi David:
>>
>> Even thought the exception says something about "addAll is not a supported operation in com.webobjects.foundation.NSArray" that is not what causes this issue. We experienced a similar issue. The problem for us was that we were using dependent WOBrowser components (that's what it sounds like you are doing) and bind the list binding of the dependent WOBrowser to a method that has a conditional base upon what was selected in the first WOBrowser, e.g.
>>
>> categoryWOBrowser : WOBrowser {
>> ...
>> selection = selectedCategory;
>> ...
>> }
>>
>> dependentWOBrowser : WOBrowser {
>> list = dependentList;
>> ...
>> }
>>
>> public NSArray dependentList() {
>> if (selectedCategory == "ABC") return category1Array;
>> else if (selectedCategory == "DEF") return category2Array
>> ...
>> }
>>
>> If you change the selectedCategory and submit the form (via Ajax or form submit) then in takeValuesFromRequest the dependentWOBrowser list binding gets evaluated and the method returns a different list. But the list should really not change until appendToResponse.
>>
>> In our case, we set dependentList in appendToResponse, so dependentList becomes a setter/getter.
>>
>> Michael.
>>
>> On 1/25/2012 4:27 AM, Farrukh Ijaz wrote:
>>> Hi David,
>>>
>>> From the exception it looks like you're trying to call addAll method on
>>> NSArray which is not mutable. Since NSArray is an instance of List
>>> interface therefore the check at line 532 returns true and therefore
>>> addAll get's called at link 533 and that's actually raising exception.
>>>
>>> Fix: Make sure listClassInContext(context) method is returning mutable
>>> object most likely NSMutableArray.
>>>
>>> Farrukh
>>>
>>> On 2012-01-25, at 1:21 PM, David Avendasora wrote:
>>>
>>>> Hey all,
>>>>
>>>> I'm in over my head again. But at least the "good" news is that I
>>>> think I'm finally inching my way toward the deep end of the pool...
>>>>
>>>> We're suddenly running into the WOBrowser
>>>> "java.lang.UnsupportedOperationException: addAll is not a supported
>>>> operation in com.webobjects.foundation.NSArray" problem as others have
>>>> run into.
>>>
>>>> We have a WOComponent that has three WOBrowsers on it. One selects one
>>>> or more "Categories" from all possibilities. The other two manage what
>>>> related objects are related to the selected Categories. One with
>>>> Available Objects, and one with Assigned Objects. Basically, with 3
>>>> WOBrowsers we are managing a Many-to-Many relationship.
>>>>
>>>> Now, we can easily avoid the error by just making sure that the
>>>> "selections" bindings of the WOBrowsers are not null. Initializing
>>>> them with NSArray.emptyArray() works just fine.
>>>>
>>>> There are two odd things:
>>>> 1) We just started running into this problem and this code has been
>>>> running unchanged for years, and Wonder's last change was 16+ months ago
>>>> 2) There are three WOBrowsers on the Page (2 in one component, 1 in a
>>>> parent component) and only ONE of the WOBrowsers is causing this error.
>>>>
>>>> I believe there is a bug in WO's or WOnder's handling of WOBrowser,
>>>> but maybe (probably) I'm just not fully understanding the implications
>>>> of multiple WOBrowsers in one Page and the Request-Response loop.
>>>>
>>>> 526if(_selections!=null&&_selections.isValueSettable()) {
>>>> 526 try {
>>>> 527 ClassresultClass=listClassInContext(context);
>>>> 528 Object result = resultClass.newInstance();
>>>> 529 if(resultinstanceofNSMutableArray) {
>>>> 530 ((NSMutableArray)result).addObjects(selections.toArray());
>>>> 531 } else {
>>>> 532 if(result instanceof List) {
>>>> 533 ((List)result).addAll(selections);
>>>> 534 }
>>>> 535 }
>>>> 536 _selections.setValue(result,context.component());
>>>> 537 } catch(Exception exception) {
>>>>
>>>> If I add the following two lines:
>>>>
>>>> 531 + } else if (result instanceof NSArray) {
>>>> 532 + result = new NSArray(selections.toArray());
>>>>
>>>> Or surround lines 529 - 535 with the following if clause:
>>>>
>>>> 529 + if(selections !=null&&!selections.isEmpty()) {
>>>> ...
>>>> 537 +}
>>>>
>>>> Then everything works just fine, even if the selections bindings end
>>>> up null.
>>>>
>>>> That's all very special, but it just covers up the real problem by
>>>> intercepting the bad data before it can cause an error. They don't fix
>>>> what is causing the bad data in the first place.
>>>>
>>>> It appears that for some reason line 527's call to
>>>> EOAssociation#listClassInContext(context)for just ONE of the three
>>>> WOBrowsers returns an instance of NSArray instead of an
>>>> NSMutableArray. The one that gets an NSArray Class is the third
>>>> WOBrowser on the page, but possibly more significantly it'sthe second
>>>> with a null "selections" binding.
>>>>
>>>> What I don't get is why would
>>>> EOAssociation#listClassInContext(context)return different Class
>>>> objects (NSMutableArray for the first, NSArray for the second) even
>>>> when both WOBrowser "selections" bindings are null?
>>>>
>>>> Does anybody have any ideas?
>>>>
>>>> (Clarification for Chuck: I mean ideas that don't directly or
>>>> indirectly involve bourbon and/or hookers)
>>>>
>>>> Dave
>>>>
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list (email@hidden
>>>> <mailto:email@hidden>)
>>>> Help/Unsubscribe/Update your Subscription:
>>>>
>>>> This email sent to email@hidden
>>>
>>>
>>>
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list (email@hidden)
>>> Help/Unsubscribe/Update your Subscription:
>>>
>>> This email sent to email@hidden
>>
>> --
>> Tel: (602) 279-4600 ext: 635
>> Desert Sky Software: www.desertsky.com
>> Specializing in the Development and Hosting of
>> e-Business Applications.
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>>
>>
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden