001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.ui.web.directory;
021
022import java.io.Serializable;
023import java.text.Collator;
024import java.util.Comparator;
025import java.util.Locale;
026
027import javax.faces.context.FacesContext;
028
029import org.apache.commons.lang.StringUtils;
030
031/**
032 * @author <a href="mailto:glefter@nuxeo.com">George Lefter</a>
033 */
034public class DirectorySelectItemComparator implements Comparator<DirectorySelectItem>, Serializable {
035
036    private static final long serialVersionUID = 1L;
037
038    private final String[] ordering;
039
040    private Boolean caseSensitive;
041
042    private Collator collator;
043
044    private Locale locale;
045
046    public DirectorySelectItemComparator(String ordering, Boolean caseSensitive, Locale locale) {
047        this.ordering = StringUtils.split(ordering, ",");
048        this.caseSensitive = caseSensitive;
049        if (locale == null) {
050            FacesContext context = FacesContext.getCurrentInstance();
051            this.locale = context.getViewRoot().getLocale();
052        } else {
053            this.locale = locale;
054        }
055        collator = Collator.getInstance(this.locale);
056        if (Boolean.TRUE.equals(this.caseSensitive)) {
057            collator.setStrength(Collator.TERTIARY); // TERTIARY will make a
058                                                     // difference between 'a'
059                                                     // and 'A'
060        } else {
061            collator.setStrength(Collator.SECONDARY);
062        }
063    }
064
065    public DirectorySelectItemComparator(String ordering, Boolean caseSentitive) {
066        this(ordering, caseSentitive, null);
067    }
068
069    public DirectorySelectItemComparator(String ordering) {
070        this(ordering, Boolean.FALSE);
071    }
072
073    protected int compareField(String field, DirectorySelectItem item1, DirectorySelectItem item2) {
074        if ("label".equals(field)) {
075            String label1 = item1.getLabel();
076            String label2 = item2.getLabel();
077            return collator.compare(label1, label2);
078        } else if ("id".equals(field)) {
079            String value1 = String.valueOf(item1.getValue());
080            String value2 = String.valueOf(item2.getValue());
081            // TODO: maybe deal with numbers comparisons (?)
082            return collator.compare(value1, value2);
083        } else if ("ordering".equals(field)) {
084            long orderItem1 = item1.getOrdering();
085            long orderItem2 = item2.getOrdering();
086            return Long.valueOf(orderItem1).compareTo(Long.valueOf(orderItem2));
087        } else {
088            throw new RuntimeException("Invalid sort criteria " + field);
089        }
090    }
091
092    @Override
093    public int compare(DirectorySelectItem item1, DirectorySelectItem item2) {
094        for (String field : ordering) {
095            int compare = compareField(field, item1, item2);
096            if (compare != 0) {
097                return compare;
098            }
099        }
100        return 0;
101    }
102
103}