/* * Copyright (C) NetStruxr, Inc. All rights reserved. * * This software is published under the terms of the NetStruxr * Public Software License version 0.5, a copy of which has been * included with this distribution in the LICENSE.NPL file. */ package er.extensions.components; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.eocontrol.EOSortOrdering; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSNotificationCenter; import com.webobjects.foundation.NSSelector; import er.extensions.foundation.ERXStringUtilities; import er.extensions.localization.ERXLocalizer; import er.extensions.woextensions.WOSortOrder; ////////////////////////////////////////////////////////////////////////////////////////////////////// // ERSortOrder is an extension of WOSortOrder. It adds two main abilities to WOSortOrder. // 1) It providers the ability to use custom images for the different sorting states // 2) It posts a notification when the sort ordering changes. This second one is nice // if you want the app to 'remember' what the last sort was for a user. ////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Better sort order changer. Useful for providing custom sort order images and remembering the sort orderings. * * @binding d2wContext * @binding displayGroup * @binding displayKey * @binding key * @binding unsortedImageSrc * @binding sortedAscendingImageSrc * @binding sortedDescendingImageSrc * @binding unsortedImageName * @binding sortedAscendingImageName * @binding sortedDescendingImageName * @binding imageFramework * @binding width the width of the image * @binding height the height of the image */ public class ERXSortOrder extends WOSortOrder { /** * Do I need to update serialVersionUID? * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a> */ private static final long serialVersionUID = 1L; public ERXSortOrder(WOContext context) { super(context); } private final static Logger log = LoggerFactory.getLogger(ERXSortOrder.class); //////////////////////////////////////////////// Notification Hooks ////////////////////////////////////////// public final static String SortOrderingChanged = "SortOrderingChanged"; //////////////////////////////////////////////// States ////////////////////////////////////////////////////// public final static int Reset = -1; public final static int Unsorted = 0; public final static int SortedAscending = 1; public final static int SortedDescending = 2; @Override public boolean synchronizesVariablesWithBindings() { return false; } @Override public void reset() { super.reset(); _currentState = Reset; } protected int _currentState = Reset; public int currentState() { if (_currentState == Reset) { _currentState = Unsorted; if (_isCurrentKeyPrimary()) { NSSelector aCurrentState = _primaryKeySortOrderingSelector(); if (aCurrentState.equals(EOSortOrdering.CompareAscending) || aCurrentState.equals(EOSortOrdering.CompareCaseInsensitiveAscending)) { _currentState = SortedAscending; } else if (aCurrentState.equals(EOSortOrdering.CompareDescending) || aCurrentState.equals(EOSortOrdering.CompareCaseInsensitiveDescending)) { _currentState = SortedDescending; } } } return _currentState; } public boolean hasCustomImageSrcForCurrentState() { boolean hasCustomImage = false; switch(currentState()) { case Unsorted: hasCustomImage = !ERXStringUtilities.stringIsNullOrEmpty((String)valueForBinding("unsortedImageSrc")); break; case SortedAscending: hasCustomImage = !ERXStringUtilities.stringIsNullOrEmpty((String)valueForBinding("sortedAscendingImageSrc")); break; case SortedDescending: hasCustomImage = !ERXStringUtilities.stringIsNullOrEmpty((String)valueForBinding("sortedAscendingImageSrc")); break; } return hasCustomImage; } public boolean hasCustomImageNameForCurrentState() { boolean hasCustomImage = false; switch(currentState()) { case Unsorted: hasCustomImage = !ERXStringUtilities.stringIsNullOrEmpty((String)valueForBinding("unsortedImageName")); break; case SortedAscending: hasCustomImage = !ERXStringUtilities.stringIsNullOrEmpty((String)valueForBinding("sortedAscendingImageName")); break; case SortedDescending: hasCustomImage = !ERXStringUtilities.stringIsNullOrEmpty((String)valueForBinding("sortedDescendingImageName")); break; } return hasCustomImage; } public String imageNameForCurrentState() { String imageName = null; switch(currentState()) { case Unsorted: imageName = unsortedImageName(); break; case SortedAscending: imageName = sortedAscendingImageName(); break; case SortedDescending: imageName = sortedDescendingImageName(); break; } return imageName; } public String customImageSrcForCurrentState() { String src = null; switch(currentState()) { case Unsorted: src = (String)valueForBinding("unsortedImageSrc"); break; case SortedAscending: src = (String)valueForBinding("sortedAscendingImageSrc"); break; case SortedDescending: src = (String)valueForBinding("sortedDescendingImageSrc"); break; } return src; } @Override public String frameworkName() { return hasCustomImageNameForCurrentState() ? (hasBinding("frameworkName") ? (String)valueForBinding("frameworkName") : "app") : "JavaWOExtensions"; } public String unsortedImageName() { return hasBinding("unsortedImageName") ? (String)valueForBinding("unsortedImageName") : "Unsorted.gif"; } public String sortedAscendingImageName() { return hasBinding("sortedAscendingImageName") ? (String)valueForBinding("sortedAscendingImageName") : "Ascending.gif"; } public String sortedDescendingImageName() { return hasBinding("sortedDescendingImageName") ? (String)valueForBinding("sortedDescendingImageName") : "Descending.gif"; } public Object width() { return hasBinding("width") ? valueForBinding("width") : "9"; } public Object height() { return hasBinding("height") ? valueForBinding("height") : "11"; } // FIXME: Should post a notification even if d2wContext isn't bound. @Override public WOComponent toggleClicked() { super.toggleClicked(); Object context = valueForBinding("d2wContext"); log.debug("toggleClicked {}", context); if (context != null) { NSNotificationCenter.defaultCenter().postNotification(SortOrderingChanged, displayGroup().sortOrderings(), new NSDictionary(context, "d2wContext")); } return null; } @Override public String helpString() { return ERXLocalizer.currentLocalizer().localizedTemplateStringForKeyWithObject("ERXSortOrder.sortBy", this); } // These come right out of WOSortOrder, but have protected access instead of private. protected EOSortOrdering _primarySortOrdering() { NSArray nsarray = displayGroup().sortOrderings(); if (nsarray != null && nsarray.count() > 0) { EOSortOrdering eosortordering = (EOSortOrdering)nsarray.objectAtIndex(0); return eosortordering; } return null; } protected NSSelector _primaryKeySortOrderingSelector() { EOSortOrdering eosortordering = _primarySortOrdering(); NSSelector nsselector = null; if(eosortordering != null) nsselector = eosortordering.selector(); return nsselector; } protected boolean _isCurrentKeyPrimary() { EOSortOrdering eosortordering = _primarySortOrdering(); return eosortordering != null && eosortordering.key() != null && eosortordering.key().equals(key()); } }