001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.util;
016    
017    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
018    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
019    import com.liferay.portal.kernel.util.DateUtil;
020    import com.liferay.portal.kernel.util.OrderByComparator;
021    import com.liferay.portal.kernel.util.OrderByComparatorFactory;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    
025    import java.util.Date;
026    import java.util.HashMap;
027    import java.util.Map;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     */
032    @DoPrivileged
033    public class OrderByComparatorFactoryImpl implements OrderByComparatorFactory {
034    
035            @Override
036            public OrderByComparator create(String tableName, Object... columns) {
037                    if ((columns.length == 0) || ((columns.length % 2) != 0)) {
038                            throw new IllegalArgumentException(
039                                    "Columns length is not an even number");
040                    }
041    
042                    return new DefaultOrderByComparator(tableName, columns);
043            }
044    
045            protected static class DefaultOrderByComparator extends OrderByComparator {
046    
047                    @Override
048                    public int compare(Object object1, Object object2) {
049                            for (int i = 0; i < _columns.length; i += 2) {
050                                    String columnName = String.valueOf(_columns[i]);
051                                    boolean columnAscending = Boolean.valueOf(
052                                            String.valueOf(_columns[i + 1]));
053    
054                                    Object columnInstance = null;
055    
056                                    Class<?> columnClass = BeanPropertiesUtil.getObjectTypeSilent(
057                                            object1, columnName);
058    
059                                    if (columnClass.isPrimitive()) {
060                                            columnInstance = _primitiveObjects.get(columnClass);
061                                    }
062                                    else {
063                                            try {
064                                                    columnInstance = columnClass.newInstance();
065                                            }
066                                            catch (Exception e) {
067                                            }
068                                    }
069    
070                                    Object columnValue1 = BeanPropertiesUtil.getObjectSilent(
071                                            object1, columnName);
072                                    Object columnValue2 = BeanPropertiesUtil.getObjectSilent(
073                                            object2, columnName);
074    
075                                    if (columnInstance instanceof Date) {
076                                            Date columnValueDate1 = (Date)columnValue1;
077                                            Date columnValueDate2 = (Date)columnValue2;
078    
079                                            int value = DateUtil.compareTo(
080                                                    columnValueDate1, columnValueDate2);
081    
082                                            if (value == 0) {
083                                                    continue;
084                                            }
085    
086                                            if (columnAscending) {
087                                                    return value;
088                                            }
089                                            else {
090                                                    return -value;
091                                            }
092                                    }
093                                    else if (columnInstance instanceof Comparable<?>) {
094                                            Comparable<Object> columnValueComparable1 =
095                                                    (Comparable<Object>)columnValue1;
096                                            Comparable<Object> columnValueComparable2 =
097                                                    (Comparable<Object>)columnValue2;
098    
099                                            int value = columnValueComparable1.compareTo(
100                                                    columnValueComparable2);
101    
102                                            if (value == 0) {
103                                                    continue;
104                                            }
105    
106                                            if (columnAscending) {
107                                                    return value;
108                                            }
109                                            else {
110                                                    return -value;
111                                            }
112                                    }
113                            }
114    
115                            return 0;
116                    }
117    
118                    @Override
119                    public String getOrderBy() {
120                            StringBundler sb = new StringBundler();
121    
122                            for (int i = 0; i < _columns.length; i += 2) {
123                                    if (i != 0) {
124                                            sb.append(StringPool.COMMA);
125                                    }
126    
127                                    sb.append(_tableName);
128                                    sb.append(StringPool.PERIOD);
129    
130                                    String columnName = String.valueOf(_columns[i]);
131                                    boolean columnAscending = Boolean.valueOf(
132                                            String.valueOf(_columns[i + 1]));
133    
134                                    sb.append(columnName);
135    
136                                    if (columnAscending) {
137                                            sb.append(_ORDER_BY_ASC);
138                                    }
139                                    else {
140                                            sb.append(_ORDER_BY_DESC);
141                                    }
142                            }
143    
144                            return sb.toString();
145                    }
146    
147                    @Override
148                    public boolean isAscending(String field) {
149                            String orderBy = getOrderBy();
150    
151                            if (orderBy == null) {
152                                    return false;
153                            }
154    
155                            int x = orderBy.indexOf(
156                                    StringPool.PERIOD + field + StringPool.SPACE);
157    
158                            if (x == -1) {
159                                    return false;
160                            }
161    
162                            int y = orderBy.indexOf(_ORDER_BY_ASC, x);
163    
164                            if (y == -1) {
165                                    return false;
166                            }
167    
168                            int z = orderBy.indexOf(_ORDER_BY_DESC, x);
169    
170                            if ((z >= 0) && (z < y)) {
171                                    return false;
172                            }
173                            else {
174                                    return true;
175                            }
176                    }
177    
178                    private DefaultOrderByComparator(String tableName, Object... columns) {
179                            _tableName = tableName;
180                            _columns = columns;
181                    }
182    
183                    private static final String _ORDER_BY_ASC = " ASC";
184    
185                    private static final String _ORDER_BY_DESC = " DESC";
186    
187                    private static Map<Class<?>, Object> _primitiveObjects =
188                            new HashMap<Class<?>, Object>();
189    
190                    static {
191                            _primitiveObjects.put(boolean.class, new Boolean(true));
192                            _primitiveObjects.put(byte.class, new Byte("0"));
193                            _primitiveObjects.put(char.class, new Character('0'));
194                            _primitiveObjects.put(double.class, new Double(0));
195                            _primitiveObjects.put(float.class, new Float(0));
196                            _primitiveObjects.put(int.class, new Integer(0));
197                            _primitiveObjects.put(long.class, new Long(0));
198                            _primitiveObjects.put(short.class, new Short("0"));
199                    }
200    
201                    private Object[] _columns;
202                    private String _tableName;
203    
204            }
205    
206    }