Hi James,

The ComparisonSupport becomes transparent and used universally throughout 
the app. Here's an excerpt of one place where a sort occurs:

NSMutableArray displayedObjects = <the objects to display in a paginated 
list on the screen>
NSMutableArray sortOrderings = <a list of EOSortOrdering objects taking a 
key and an NSSelector>
EOSortOrdering.sortArrayUsingKeyOrderArray(displayedObjects, 
sortOrderings);

This is often called by clicking a little toggle icon to modify the 
"sortOrderings" array with a particular "key" and either 
"compareAscending" or "compareDescending". 

It works like a charm. The null values are placed at the very end of an 
ascending sort and placed at the beginning of a descending sort. It works 
so long as we haven't done any commits to the database. Sounds odd, I 
know, because I don't fully understand what is happening. It probably 
isn't the commit to the database itself but some other nuance. All I know 
with certainty is that I can move around the whole app and happily re-sort 
columns anywhere but as soon as I do a commit I'm no longer able to 
reliably sort columns on any page. Also, once it gets in this bad state, 
any new wosessions I start exhibit the same problem immediately. 

-- Aaron

James Cicenia <[EMAIL PROTECTED]> wrote on 31-01-2008 02:01:03 PM:

> What do you mean it no longer works after commits? 
> 
> How are you using your comparator?
> 
> -James Cicenia
> 
> On Jan 31, 2008, at 12:34 PM, [EMAIL PROTECTED] wrote:
> 
> 
> What happens when you want to sort ten values in ascending order but
> one of them is null? Does that void value get put at the beginning, 
> the middle, or the end? 
> 
> Apple decided that null values (or keyPaths that return a null 
> value) should be placed at the beginning of an array sorted in 
> ascending order. Perhaps they felt that "null is less than zero". 
> 
> For us, it seems that null values should be placed at the end of an 
> ascending sort. More often than not, null values make more sense to 
> be placed at the end of the list when working in our Domain. 
> 
> Has anyone crossed this bridge before? 
> 
> We've tried our hand at a solution which is listed at the bottom of 
> this message. It works so long as no commits have been made to the 
> database! After a commit, from any page in the app, sorting no 
> longer works as expected and often results in a K2Sort error. It's 
baffling. 
> 
> Our class extends the default sorting logic of EOSortOrdering.
> ComparisonSupport (the class that does sorting globally for WO). We 
> really only want to override "handleNulls()" but because it is both 
> private and static, we need to redo a few other methods as well. 
> Functionally, our class is identical but choose to place null values
> at the end of the list for an ascending sort. 
> 
> Here is the line we add to the Appliction's constructor to get the 
> ball rolling globally: 
> ========================== 
> 
> EOSortOrdering.ComparisonSupport.setSupportForClass(new 
> CXNullsAtEndComparisonSupport(), Object.class); 
> 
> 
> Here is the source code to the custom ComparisonSupport: 
> ========================== 
> 
> public class CXNullsAtEndComparisonSupport extends EOSortOrdering.
> ComparisonSupport { 
> 
>     public static final Logger _logger = Logger.
> getLogger(CXNullsAtEndComparisonSupport.class); 
> 
>         public CXNullsAtEndComparisonSupport() {} 
> 
>         protected static final int kNeitherNull = -42; 
> 
>         protected static int handleNulls(Object left, Object right) 
>         { 
>                 if(left == null || left == NSKeyValueCoding.NullValue) 
>                         return right != null && right != 
> NSKeyValueCoding.NullValue ? NSComparator.OrderedDescending : 
> NSComparator.OrderedSame; 
>                 return right != null && right != NSKeyValueCoding.
> NullValue ? kNeitherNull : NSComparator.OrderedAscending; 
>         } 
> 
>         private static final NSTimestampFormatter 
> defaultStringTimestampFormatter = new NSTimestampFormatter("%Y-%m-%d
> %H:%M:%S %Z"); 
> 
>         protected static NSTimestamp coerceToTimestampClass(Object 
value) 
>         { 
>                 if(value instanceof NSTimestamp) 
>                         return (NSTimestamp)value; 
>                 if(value instanceof Date) 
>                         return new NSTimestamp(((Date)value).getTime()); 

>                 if(value instanceof Number) 
>                         return new 
NSTimestamp(((Number)value).longValue()); 
>                 try { 
>                         return (NSTimestamp)
> defaultStringTimestampFormatter.parseObject((String)value); 
>                 } catch (Exception e) { 
>                         //fixme: do something more. 
>                         _logger.info("coerceToTimestampClass failed.
> Message = " + e.getMessage()); 
>                         return null; 
>                 } 
>         } 
> 
>         protected int _genericCompareTo(Object left, Object right) 
>         { 
>                 int nullCheck = handleNulls(left, right); 
>                 if(nullCheck != kNeitherNull) { 
>                         return nullCheck; 
>                 } 
>                 Class LHSClass = left.getClass(); 
>                 if(LHSClass == _NSUtilities._StringClass) 
>                         return 
left.toString().compareTo(right.toString()); 
>                 if((left instanceof Number) || LHSClass == 
> _NSUtilities._BooleanClass) 
>                         return _NSUtilities.
> compareNumbersOrBooleans(left, right); 
>                 if(left instanceof Date) 
>                 { 
>                         if(LHSClass != NSTimestamp._CLASS) 
>                                 left = coerceToTimestampClass(left); 
>                         right = coerceToTimestampClass(right); 
>                 } 
>                 if(left instanceof Comparable) 
>                         return ((Comparable)left).compareTo(right); 
>                 else 
>                         return 
left.toString().compareTo(right.toString()); 
>         } 
> 
>         protected int _genericCaseInsensitiveCompareTo(Object left, 
> Object right) 
>         { 
>                 int nullCheck = handleNulls(left, right); 
>                 if(nullCheck != kNeitherNull) 
>                         return nullCheck; 
>                 Class LHSClass = left.getClass(); 
>                 if(LHSClass == _NSUtilities._StringClass) 
>                         return left.toString().
> compareToIgnoreCase(right.toString()); 
>                 if((left instanceof Number) || LHSClass == 
> _NSUtilities._BooleanClass) 
>                         return _NSUtilities.
> compareNumbersOrBooleans(left, right); 
>                 if(left instanceof Date) 
>                 { 
>                         if(LHSClass != NSTimestamp._CLASS) 
>                                 left = coerceToTimestampClass(left); 
>                         right = coerceToTimestampClass(right); 
>                         return ((Comparable)left).compareTo(right); 
>                 } else 
>                 { 
>                         return left.toString().
> compareToIgnoreCase(right.toString()); 
>                 } 
>         } 
> 
> } _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list      ([email protected])
> Help/Unsubscribe/Update your Subscription:
> 
http://lists.apple.com/mailman/options/webobjects-dev/james%40jimijon.com
> 
> This email sent to [EMAIL PROTECTED]
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to