package org.sakaiproject.site.util; import java.text.Collator; import java.util.Comparator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.authz.api.Member; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.Group; import org.sakaiproject.site.api.SiteService.SortType; import org.sakaiproject.site.util.Participant; import org.sakaiproject.time.api.Time; import org.sakaiproject.user.cover.UserDirectoryService; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.api.EntityPropertyNotDefinedException; import org.sakaiproject.entity.api.EntityPropertyTypeException; import java.util.Locale; import java.text.RuleBasedCollator; /** * The comparator to be used in Worksite Setup/Site Info tool */ public class SiteComparator implements Comparator { private static Log log = LogFactory.getLog(SiteComparator.class); Collator collator = Collator.getInstance(); Collator localeCollator = null; /** * the criteria */ String m_criterion = null; Locale m_loc = null; String m_asc = null; /** * constructor * * @param criteria * The sort criteria string * @param asc * The sort order string. TRUE_STRING if ascending; "false" * otherwise. */ public SiteComparator(String criterion, String asc) { m_criterion = criterion; m_asc = asc; } // constructor // create a locale-sensitive comparator; on error keep localeCollator set to null so it's not used public SiteComparator(String criterion, String asc, Locale locale) { this(criterion, asc); m_loc = locale; try { RuleBasedCollator defaultCollator = (RuleBasedCollator) Collator.getInstance(locale); String rules = defaultCollator.getRules(); localeCollator = new RuleBasedCollator(rules.replaceAll("<'\u005f'", "<' '<'\u005f'")); localeCollator.setStrength(Collator.TERTIARY); } catch (Exception e) { log.warn("SiteComparator failed to create RuleBasedCollator for locale " + locale.toString(), e); localeCollator = null; } } /** * implementing the Comparator compare function * * @param o1 * The first object * @param o2 * The second object * @return The compare result. 1 is o1 < o2; -1 otherwise */ public int compare(Object o1, Object o2) { int result = -1; if (m_criterion == null) { m_criterion = SiteConstants.SORTED_BY_TITLE; } /** *********** for sorting site list ****************** */ if (m_criterion.equals(SiteConstants.SORTED_BY_TITLE)) { // sorted by the worksite title String s1 = ((Site) o1).getTitle(); String s2 = ((Site) o2).getTitle(); result = compareString(s1, s2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_DESCRIPTION)) { // sorted by the site short description String s1 = ((Site) o1).getShortDescription(); String s2 = ((Site) o2).getShortDescription(); result = compareString(s1, s2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_TYPE)) { // sorted by the site type String s1 = ((Site) o1).getType(); String s2 = ((Site) o2).getType(); result = compareString(s1, s2); } else if (m_criterion.equals(SortType.CREATED_BY_ASC.toString())) { // sorted by the site creator String s1 = ((Site) o1).getProperties().getProperty( "CHEF:creator"); String s2 = ((Site) o2).getProperties().getProperty( "CHEF:creator"); result = compareString(s1, s2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_STATUS)) { // sort by the status, published or unpublished int i1 = ((Site) o1).isPublished() ? 1 : 0; int i2 = ((Site) o2).isPublished() ? 1 : 0; if (i1 > i2) { result = 1; } else { result = -1; } } else if (m_criterion.equals(SiteConstants.SORTED_BY_JOINABLE)) { // sort by whether the site is joinable or not boolean b1 = ((Site) o1).isJoinable(); boolean b2 = ((Site) o2).isJoinable(); result = compareBoolean(b1, b2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_NAME)) { // sort by whether the site is joinable or not String s1 = null; if (o1.getClass().equals(Participant.class)) { s1 = ((Participant) o1).getName(); } String s2 = null; if (o2.getClass().equals(Participant.class)) { s2 = ((Participant) o2).getName(); } result = compareString(s1, s2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_UNIQNAME)) { // sort by whether the site is joinable or not String s1 = null; if (o1.getClass().equals(Participant.class)) { s1 = ((Participant) o1).getUniqname(); } String s2 = null; if (o2.getClass().equals(Participant.class)) { s2 = ((Participant) o2).getUniqname(); } result = compareString(s1, s2); // secondary sort based on user name if necessary if (result == 0) result = compareParticipantName((Participant) o1, (Participant) o2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_ROLE)) { String s1 = ""; if (o1.getClass().equals(Participant.class)) { s1 = ((Participant) o1).getRole(); } String s2 = ""; if (o2.getClass().equals(Participant.class)) { s2 = ((Participant) o2).getRole(); } result = compareString(s1, s2); // secondary sort based on user name if necessary if (result == 0) result = compareParticipantName((Participant) o1, (Participant) o2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_COURSE)) { // sort by whether the site is joinable or not String s1 = null; if (o1.getClass().equals(Participant.class)) { s1 = ((Participant) o1).getSection(); } String s2 = null; if (o2.getClass().equals(Participant.class)) { s2 = ((Participant) o2).getSection(); } result = compareString(s1, s2); // secondary sort based on user name if necessary if (result == 0) result = compareParticipantName((Participant) o1, (Participant) o2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_ID)) { String s1 = null; if (o1.getClass().equals(Participant.class)) { s1 = ((Participant) o1).getRegId(); } String s2 = null; if (o2.getClass().equals(Participant.class)) { s2 = ((Participant) o2).getRegId(); } result = compareString(s1, s2); // secondary sort based on user name if necessary if (result == 0) result = compareParticipantName((Participant) o1, (Participant) o2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_CREDITS)) { String s1 = null; if (o1.getClass().equals(Participant.class)) { s1 = ((Participant) o1).getCredits(); } String s2 = null; if (o2.getClass().equals(Participant.class)) { s2 = ((Participant) o2).getCredits(); } result = compareString(s1, s2); // secondary sort based on user name if necessary if (result == 0) result = compareParticipantName((Participant) o1, (Participant) o2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_PARTICIPANT_STATUS)) { boolean a1 = true; if (o1.getClass().equals(Participant.class)) { a1 = ((Participant) o1).isActive(); } boolean a2 = true; if (o2.getClass().equals(Participant.class)) { a2 = ((Participant) o2).isActive(); } // let the active users show first when sort ascendingly result = -compareBoolean(a1, a2); // secondary sort based on user name if necessary if (result == 0) result = compareParticipantName((Participant) o1, (Participant) o2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_CREATION_DATE)) { // sort by the site's creation date Time t1 = null; Time t2 = null; // get the times try { t1 = ((Site) o1).getProperties().getTimeProperty( ResourceProperties.PROP_CREATION_DATE); } catch (EntityPropertyNotDefinedException e) { } catch (EntityPropertyTypeException e) { } try { t2 = ((Site) o2).getProperties().getTimeProperty( ResourceProperties.PROP_CREATION_DATE); } catch (EntityPropertyNotDefinedException e) { } catch (EntityPropertyTypeException e) { } if (t1 == null) { result = -1; } else if (t2 == null) { result = 1; } else if (t1.before(t2)) { result = -1; } else { result = 1; } } else if (m_criterion.equals(SiteConstants.SORTED_BY_GROUP_TITLE)){ // sorted by the group title String s1 = ((Group) o1).getTitle(); String s2 = ((Group) o2).getTitle(); result = compareString(s1, s2); } else if (m_criterion.equals(SiteConstants.SORTED_BY_GROUP_SIZE)) { // sorted by the group title int n1 = ((Group) o1).getMembers().size(); int n2 = ((Group) o2).getMembers().size(); result = (n1 > n2) ? 1 : -1; } else if (m_criterion.equals(SiteConstants.SORTED_BY_MEMBER_NAME)) { // sorted by the member name String s1 = null; String s2 = null; try { s1 = UserDirectoryService .getUser(((Member) o1).getUserId()).getSortName(); } catch (Exception ignore) { } try { s2 = UserDirectoryService .getUser(((Member) o2).getUserId()).getSortName(); } catch (Exception ignore) { } result = compareString(s1, s2); } if (m_asc == null) m_asc = Boolean.TRUE.toString(); // sort ascending or descending if (m_asc.equals(Boolean.FALSE.toString())) { result = -result; } return result; } // compare /** * Serves as secondary sort by participant name if other criteria returns equal value * @param o1 * @param o2 * @return */ private int compareParticipantName(Participant o1, Participant o2) { return compareString(o1.getName(), o2.getName()); } private int compareBoolean(boolean b1, boolean b2) { int result; if (b1 == b2) { result = 0; } else if (b1 == true) { result = 1; } else { result = -1; } return result; } private int compareString(String s1, String s2) { int result; if (s1 == null && s2 == null) { result = 0; } else if (s2 == null) { result = 1; } else if (s1 == null) { result = -1; } else { if (localeCollator != null) { result = localeCollator.compare(s1, s2); } else { result = collator.compare(s1, s2); } } return result; } } // SiteComparator