001    /**
002     * Copyright (c) 2000-present 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.kernel.util;
016    
017    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
018    import com.liferay.portal.model.BaseModel;
019    
020    import java.util.Date;
021    import java.util.HashMap;
022    import java.util.Map;
023    
024    /**
025     * @author Brian Wing Shun Chan
026     */
027    public class OrderByComparatorFactoryUtil {
028    
029            public static <T extends BaseModel<T>> OrderByComparator<T> create(
030                    String tableName, Object... columns) {
031    
032                    if ((columns.length == 0) || ((columns.length % 2) != 0)) {
033                            throw new IllegalArgumentException(
034                                    "Columns length is not an even number");
035                    }
036    
037                    return new DefaultOrderByComparator<>(tableName, columns);
038            }
039    
040            protected static class DefaultOrderByComparator<T extends BaseModel<T>>
041                    extends OrderByComparator<T> {
042    
043                    @Override
044                    public int compare(T object1, T object2) {
045                            for (int i = 0; i < _columns.length; i += 2) {
046                                    String columnName = String.valueOf(_columns[i]);
047                                    boolean columnAscending = Boolean.valueOf(
048                                            String.valueOf(_columns[i + 1]));
049    
050                                    Object columnInstance = null;
051    
052                                    Class<?> columnClass = BeanPropertiesUtil.getObjectTypeSilent(
053                                            object1, columnName);
054    
055                                    if (columnClass.isPrimitive()) {
056                                            columnInstance = _primitiveObjects.get(columnClass);
057                                    }
058                                    else {
059                                            try {
060                                                    columnInstance = columnClass.newInstance();
061                                            }
062                                            catch (Exception e) {
063                                            }
064                                    }
065    
066                                    Object columnValue1 = BeanPropertiesUtil.getObjectSilent(
067                                            object1, columnName);
068                                    Object columnValue2 = BeanPropertiesUtil.getObjectSilent(
069                                            object2, columnName);
070    
071                                    if (columnInstance instanceof Date) {
072                                            Date columnValueDate1 = (Date)columnValue1;
073                                            Date columnValueDate2 = (Date)columnValue2;
074    
075                                            int value = DateUtil.compareTo(
076                                                    columnValueDate1, columnValueDate2);
077    
078                                            if (value == 0) {
079                                                    continue;
080                                            }
081    
082                                            if (columnAscending) {
083                                                    return value;
084                                            }
085                                            else {
086                                                    return -value;
087                                            }
088                                    }
089                                    else if (columnInstance instanceof Comparable<?>) {
090                                            Comparable<Object> columnValueComparable1 =
091                                                    (Comparable<Object>)columnValue1;
092                                            Comparable<Object> columnValueComparable2 =
093                                                    (Comparable<Object>)columnValue2;
094    
095                                            int value = columnValueComparable1.compareTo(
096                                                    columnValueComparable2);
097    
098                                            if (value == 0) {
099                                                    continue;
100                                            }
101    
102                                            if (columnAscending) {
103                                                    return value;
104                                            }
105                                            else {
106                                                    return -value;
107                                            }
108                                    }
109                            }
110    
111                            return 0;
112                    }
113    
114                    @Override
115                    public String getOrderBy() {
116                            StringBundler sb = new StringBundler(5 * _columns.length - 1);
117    
118                            for (int i = 0; i < _columns.length; i += 2) {
119                                    if (i != 0) {
120                                            sb.append(StringPool.COMMA);
121                                    }
122    
123                                    sb.append(_tableName);
124                                    sb.append(StringPool.PERIOD);
125    
126                                    String columnName = String.valueOf(_columns[i]);
127                                    boolean columnAscending = Boolean.valueOf(
128                                            String.valueOf(_columns[i + 1]));
129    
130                                    sb.append(columnName);
131    
132                                    if (columnAscending) {
133                                            sb.append(_ORDER_BY_ASC);
134                                    }
135                                    else {
136                                            sb.append(_ORDER_BY_DESC);
137                                    }
138                            }
139    
140                            return sb.toString();
141                    }
142    
143                    @Override
144                    public boolean isAscending(String field) {
145                            String orderBy = getOrderBy();
146    
147                            if (orderBy == null) {
148                                    return false;
149                            }
150    
151                            int x = orderBy.indexOf(
152                                    StringPool.PERIOD + field + StringPool.SPACE);
153    
154                            if (x == -1) {
155                                    return false;
156                            }
157    
158                            int y = orderBy.indexOf(_ORDER_BY_ASC, x);
159    
160                            if (y == -1) {
161                                    return false;
162                            }
163    
164                            int z = orderBy.indexOf(_ORDER_BY_DESC, x);
165    
166                            if ((z >= 0) && (z < y)) {
167                                    return false;
168                            }
169                            else {
170                                    return true;
171                            }
172                    }
173    
174                    private DefaultOrderByComparator(String tableName, Object... columns) {
175                            _tableName = tableName;
176                            _columns = columns;
177                    }
178    
179                    private static final String _ORDER_BY_ASC = " ASC";
180    
181                    private static final String _ORDER_BY_DESC = " DESC";
182    
183                    private static final Map<Class<?>, Object> _primitiveObjects =
184                            new HashMap<>();
185    
186                    static {
187                            _primitiveObjects.put(boolean.class, Boolean.TRUE);
188                            _primitiveObjects.put(byte.class, Byte.valueOf("0"));
189                            _primitiveObjects.put(char.class, Character.valueOf('0'));
190                            _primitiveObjects.put(double.class, Double.valueOf(0));
191                            _primitiveObjects.put(float.class, Float.valueOf(0));
192                            _primitiveObjects.put(int.class, Integer.valueOf(0));
193                            _primitiveObjects.put(long.class, Long.valueOf(0));
194                            _primitiveObjects.put(short.class, Short.valueOf("0"));
195                    }
196    
197                    private final Object[] _columns;
198                    private final String _tableName;
199    
200            }
201    
202    }